4 대의 카메라에서 동시에 비디오를 캡처하는 프로그램을 작성하고 있으므로 각 카메라를 제어하는 4 개의 스레드가 있습니다. 각 스레드에서 키를 누르기 전까지 계속 캡쳐를하고 키는 'q'또는 그와 일치합니다. 나는이 같은 인터넷과 발견 방법을 검색 키를 누를 때 손잡이를 들어리눅스에서 다중 스레드 프로그램에서 C++이 키 누르기를 처리합니다.
:
static void *capureVideo(void *para) {
// Some code...
while(!(kbhit('q') {
// Read frame...
}
}
void creatThread() {
if (pthread_create(&threadID, NULL, capureVideo, this) != 0) {
perror("thread create faild");
exit(EXIT_FAILURE);
}
}
하면 프로그램이 실행 :
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
int kbhit(int key) {
int ch;
int old_file_status;
struct termios old_term_attr;
struct termios new_term_attr;
tcgetattr(STDIN_FILENO, &old_term_attr);
new_term_attr = old_term_attr;
new_term_attr.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &new_term_attr);
old_file_status = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, old_file_status | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &old_term_attr);
fcntl(STDIN_FILENO, F_SETFL, old_file_status);
if(ch == c)
return 1;
return 0;
}
그리고 (완료되지 않음)이 같은 코드를 내 VideoCapture 클래스의
일단 'q'키를 4 번 누르면 프로그램이 종료되고 제어가 쉘로 돌아갑니다. 그러나 특정 상황 (정확하게 모르지만 매번 발생하지 않음)에서 문제가 발생합니다. 즉, 쉘에 명령을 입력하면 입력 한 문자가 표시되지 않습니다. Enter 키를 누르면 명령이 제출됩니다.이 문제점을 검색하여 다음을 찾았습니다. https://askubuntu.com/a/172747 : 터미널 특성이 올바르게 재설정되지 않았 음을 나타냅니다. 그러나 keypress 핸들 코드에서이 두 줄의 코드가 나타났습니다.
tcsetattr(STDIN_FILENO, TCSANOW, &old_term_attr);
fcntl(STDIN_FILENO, F_SETFL, old_file_status);
은 터미널 속성을 재설정했습니다. 그래서 멀티 스레드와 관련이 있는지 궁금합니다. 나는 mutlithread 프로그래밍에 익숙하지 않고 그것을 스스로 해결할 수 없기 때문에 누군가 나를 도울 수 있습니까? 모든 제안은 높이 평가됩니다. 터미널 속성은 완전히 무작위이없이
tcgetattr(STDIN_FILENO, &old_term_attr);
new_term_attr = old_term_attr;
new_term_attr.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &new_term_attr);
이 고정되고 :
CTRL-C 또는 다른 신호로 프로그램이 종료되면 수동으로 터미널 속성을 재설정해도 아무런 성과가 없습니다. 명시 적으로 터미널 속성을 기본값으로 재설정하는 것 외에도, 시그널 핸들러는 최소한'SIGINT','SIGHUP','SIGTERM', 그리고 아마도'SIGQUIT'에 대해서'sigaction()'을 통해 설정되어야합니다. 터미널 속성을 기본값으로 재설정합니다. –
다른 스레드가'getchar()'을 입력하기 직전에 터미널 속성을 기본값으로 재설정하고 표준 입력에서 블로킹을 끝내는 경합 조건도 있습니다. 전반적으로 버그 투성이입니다. 터미널은 처음에는 비 차단 모드와 비표준 처리 모드로 설정되어야하며 프로그램이 종료되기 전에만 재설정되어야합니다. 그리고'getchar()'대신에 파일 기술자 0에서'read()'를 사용하십시오. –
'터미널은 비 차단 모드와 비표준 처리 모드로 시작될 때 한 번만 설정되어야하고 프로그램이 종료되기 전에 재설정되어야합니다 그것이 싱글 톤 패턴을 사용할 수 있다는 것을 의미합니까? 또한'getchar()'이 권장되지 않는 이유를 설명 할 수 있습니까? 고맙습니다. @SamVarshavchik – Gzy