이글은 예전 제 싸이월드 블로그에 작성한 글을 티스토리로 옮긴 것입니다.
원문 : http://cy.cyworld.com/home/21147242/post/4FE7CE007255739A07C68401
원문 작성일 : 2012.06.25
------------------------------------------------------------------------------------------
첨부파일 : getChar.zip
getchar() 함수를 클래스화 시켜서 좀 편하게 써보자 생각함.
getChar.h 랑 getChar.cpp 두개의 파일을 둠.
쉽게 생각했다가 프로그램 종료 시, getchar() 에서 블럭걸리는 증상 발견됨.
하루종일 방법을 고민하다 못찾고 kldp 에 물어 봄.
http://kldp.org/node/133482
pipe(), select() 함수를 사용하여 어케어케 함. 공부할게 생겼다.
위 답변을 가지고 아래처럼 정리하여 동작함을 확인하였다.
제일 아래 main.cpp 에 클래스 사용 예제가 있다.
############ getChar.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
#ifndef _GETCHAR_H_
#define _GETCHAR_H_
#include "pthread.h"
typedef void (*CALLBACK_GETCHAR)(char ) ;
class CGetChar
{
public :
CGetChar() ;
~CGetChar() ;
int init(CALLBACK_GETCHAR callback) ;
int stop() ;
int destroy(void) ;
// This only use in callback function.
CALLBACK_GETCHAR m_callbackGetChar ;
int m_flagStop ;
private :
pthread_t m_thGetChar ;
};
#endif
|
############ getChar.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 |
#include "getChar.h"
#include<stdio.h>
#include<termio.h>
#include<unistd.h>
#include<fcntl.h>
static int poll_getch[2] = {-1, -1} ;
void* threadGetChar(void* pData)
{
int fd_cancel, fd_stdin, ch ;
struct termios org_term, new_term ;
fd_set rdfds ;
int max_fd ;
int r ;
CGetChar* pGetChar = (CGetChar*)pData ;
while(1)
{
fd_cancel = poll_getch[0] ;
fd_stdin = fileno(stdin) ;
ch = -1 ;
tcgetattr(fd_stdin,&org_term) ;
new_term = org_term ;
new_term.c_lflag&= ~(ICANON | ECHO) ;
new_term.c_cc[VTIME] = 0 ;
new_term.c_cc[VMIN] = 1 ;
tcsetattr(fd_stdin, TCSANOW,&new_term) ;
FD_ZERO(&rdfds) ;
FD_SET(fd_stdin,&rdfds) ;
FD_SET(fd_cancel,&rdfds) ;
max_fd = fd_stdin>fd_cancel ? fd_stdin : fd_cancel ;
r = select(max_fd + 1,&rdfds, NULL, NULL, NULL) ;
if( r>0&&FD_ISSET(fd_stdin,&rdfds))
ch = getchar() ;
tcsetattr(fd_stdin, TCSANOW,&org_term) ;
pGetChar->m_callbackGetChar(ch) ;
if(pGetChar->m_flagStop)
break ;
usleep(1000) ;
}
return 0 ;
}
CGetChar::CGetChar() :
m_flagStop(0)
{
}
CGetChar::~CGetChar()
{
}
int CGetChar::init(CALLBACK_GETCHAR callback)
{
if(pipe(poll_getch)<0)
{
perror("pipe") ;
return 1 ;
}
m_callbackGetChar = callback;
pthread_create(&m_thGetChar, NULL,&threadGetChar, (void*)this) ;
return 1 ;
}
int CGetChar::stop()
{
m_flagStop = 1 ;
int fd = poll_getch[0] ;
if( fd>= 0)
write(poll_getch[1],&fd, 1) ;
return 1 ;
}
int CGetChar::destroy(void)
{
int nStatus ;
m_flagStop = 0 ;
if(!m_flagStop)
{
int fd = poll_getch[0] ;
if( fd>= 0)
write(poll_getch[1],&fd, 1) ;
m_flagStop = 1 ;
}
pthread_join(m_thGetChar, (void**)&nStatus) ;
return 1 ;
}
|
############# main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 |
#include<cstdio>
#include<unistd.h>
#include "getChar.h"
#include<termio.h>
typedef void (*CALLBACK_GETCHAR)(char ) ;
static char m_char ;
void cbGetChar(char ch)
{
m_char = ch ;
printf("ch : %c\n", m_char) ;
}
int main()
{
CGetChar getChar ;
getChar.init(&cbGetChar) ;
while(1)
{
if(m_char == 'q')
{
getChar.stop() ;
break ;
}
usleep(1000) ;
}
getChar.destroy() ;
usleep(1000) ;
return 1 ;
}
|
첨부파일 : getChar.zip
'삽질미학 > C,C++' 카테고리의 다른 글
[Linux C/C++] 실행파일 생성시간을 이용한 버전관리 (0) | 2016.10.24 |
---|---|
TDES-ECB 암호화 코드 (0) | 2016.10.24 |
C++ 코드를 C에서 사용하기 (0) | 2016.10.14 |
C 에서 STL map 컨테이너를... - SCL 소개 (0) | 2016.10.14 |
C 코드로 C++ 의 다형성 흉내내기 (0) | 2016.10.14 |