당신은 C에서 리눅스에서 논블로킹 콘솔 I/O를 어떻게 합니까?
C의 Linux/OS X에서 논블로킹 콘솔 IO를 어떻게 수행합니까?
예를 하나 추가합니다.
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char const *argv[]) {
char buf[20];
fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
sleep(4);
int numRead = read(0, buf, 4);
if (numRead > 0) {
printf("You said: %s", buf);
}
}
이 프로그램을 실행하면 표준 입력을 제공하는 데 4초가 걸립니다.입력을 찾을 수 없으면 반환됩니다.
2개의 샘플 실행:
$ ./a.out
fda
You said: fda
$ ./a.out
$
Pete Kirkham처럼, 저는 cc.byexamples.com 을 찾았습니다. 그리고 그것은 저에게 효과가 있었습니다.문제에 대한 설명과 ncurs 버전을 보려면 해당 사이트로 이동하십시오.
내 코드는 표준 입력 또는 파일에서 초기 명령을 가져온 다음 초기 명령이 처리되는 동안 취소 명령을 기다려야 했습니다.이지만, 은 내코는 C++이만, 은당사수합있니다야어를 할 수 것입니다.scanf()
++ 하는 나머지 C++ 입력 기능입니다.getline()
.
고기는 사용 가능한 입력이 있는지 확인하는 기능입니다.
#include <unistd.h>
#include <stdio.h>
#include <sys/select.h>
// cc.byexamples.com calls this int kbhit(), to mirror the Windows console
// function of the same name. Otherwise, the code is the same.
bool inputAvailable()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return (FD_ISSET(0, &fds));
}
함수보다 . stdin을 했을 때. 사용할 때std::cin
이 함수를 사용하기 전에는 다시는 true를 반환하지 않았습니다.를 들면, 들면를예,main()
다음과 같은 루프가 있습니다.
int main(int argc, char* argv[])
{
std::string initialCommand;
if (argc > 1) {
// Code to get the initial command from a file
} else {
while (!inputAvailable()) {
std::cout << "Waiting for input (Ctrl-C to cancel)..." << std::endl;
sleep(1);
}
std::getline(std::cin, initialCommand);
}
// Start a thread class instance 'jobThread' to run the command
// Start a thread class instance 'inputThread' to look for further commands
return 0;
}
스레드에서 이으로 " 스레드추었으며되가다에처니습로리었되으적정이기는입력열기에서대이령명새▁the▁in"에 의해 되었습니다.jobThread
.inputThread
다음과 같이 생겼습니다.
THREAD_RETURN inputThread()
{
while( !cancelled() ) {
if (inputAvailable()) {
std::string nextCommand;
getline(std::cin, nextCommand);
commandQueue.lock();
commandQueue.add(nextCommand);
commandQueue.unlock();
} else {
sleep(1);
}
}
return 0;
}
이기은아다있것입었다니을음에마에 있었을 것입니다.main()
기존 코드베이스로 작업 중이지 반대가 아닙니다
제 시스템의 경우, 새로운 라인이 전송될 때까지 사용 가능한 입력이 없었습니다.입력할 때 모든 문자를 읽으려면 stdin에서 "discovery mode"를 꺼야 합니다. cc.byexamples.com 에는 제가 시도하지 않은 제안이 몇 가지 있지만 나머지는 효과가 있어요.
당신은, 정말로.TTY(콘솔)는 상당히 제한적인 장치이며, 비차단 I/O를 거의 수행하지 않습니다.예를 들어, 저주/ncurs 애플리케이션에서 비차단 I/O와 같은 것을 볼 때 수행하는 작업을 원시 I/O라고 합니다.원시 I/O에서는 문자 해석, 삭제 처리 등이 없습니다.대신, 당신은 다른 일을 하는 동안 데이터를 확인하는 당신만의 코드를 작성해야 합니다.
현대의 C 프로그램에서는 콘솔 I/O를 스레드 또는 경량 프로세스에 넣어 이를 다른 방식으로 단순화할 수 있습니다.그런 다음 I/O는 일반적인 차단 방식으로 진행될 수 있지만 데이터는 다른 스레드에서 처리하기 위해 대기열에 삽입될 수 있습니다.
갱신하다
여기 그것에 대해 더 자세히 설명하는 저주 튜토리얼이 튜토리얼이 있습니다.
이달 초 논블로킹, 논버퍼 콘솔 입력이 필요할 것으로 생각했을 때 "Non-blocking user in loop with ncurs"를 북마크했는데, 그렇지 않아 작동 여부를 보증할 수 없습니다.나는 사용자가 엔터를 누를 때까지 입력이 안 되는 것을 신경 쓰지 않아서 그냥 aio로 stdin을 읽었습니다.
C++을 사용한 관련 질문입니다. -- stdin/stdout/stderr의 C++ IO를 차단하지 않는 크로스 플랫폼(linux/Win32)
ncurs 또는 스레드를 사용하는 또 다른 방법은 GNU Readline, 특히 콜백 함수를 등록할 수 있는 부분을 사용하는 것입니다.패턴은 다음과 같습니다.
- STDIN에서 select()를 사용합니다(다른 설명자 중에서).
- STDIN을 읽을 준비가 되었다는 메시지가 표시되면 readline의 rl_callback_read_char()를 호출합니다.
- 사용자가 전체 회선을 입력한 경우 rl_callback_read_char가 콜백을 호출합니다.그렇지 않으면 즉시 반환되고 다른 코드가 계속 진행될 수 있습니다.
Linux 유틸리티 중 하나에서 어떻게 작동하는지 살펴보겠습니다.예를 들어 perf/built-in-top.c 소스(간체):
static void *display_thread(void *arg)
{
struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
struct termios save;
set_term_quiet_input(&save);
while (!done) {
switch (poll(&stdin_poll, 1, delay_msecs)) {
...
}
}
tcsetattr(0, TCSAFLUSH, &save);
}
따라서 사용 가능한 데이터가 있는지 확인하려면 poll()을 사용하거나 다음과 같이 선택()할 수 있습니다.
#include <sys/poll.h>
...
struct pollfd pfd = { .fd = 0, .events = POLLIN };
while (...) {
if (poll(&pfd, 1, 0)>0) {
// data available, read it
}
...
}
이 경우 [RETURN] 키를 누른 후 각 키가 아닌 전체 라인에서 이벤트를 수신합니다.터미널이 표준 모드에서 작동하기 때문입니다(입력 스트림은 버퍼링되고 [RETURN]을 누르면 버퍼 플러시됨).
표준 입력 처리 모드에서 단말기 입력은 새 줄('\n'), EOF 또는 EOL 문자로 끝나는 줄로 처리됩니다.사용자가 전체 라인을 입력할 때까지 어떤 입력도 읽을 수 없으며, 읽기 기능(입력 및 출력 기본값 참조)은 요청된 바이트 수에 관계없이 최대 단일 라인의 입력을 반환합니다.
문자를 즉시 읽으려면 비정규 모드를 사용할 수 있습니다.tcsetattr()을 사용하여 다음을 전환합니다.
#include <termios.h>
void set_term_quiet_input()
{
struct termios tc;
tcgetattr(0, &tc);
tc.c_lflag &= ~(ICANON | ECHO);
tc.c_cc[VMIN] = 0;
tc.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &tc);
}
간단한 프로그램(놀이터 링크):
#include <stdio.h>
#include <unistd.h>
#include <sys/poll.h>
#include <termios.h>
void set_term_quiet_input()
{
struct termios tc;
tcgetattr(0, &tc);
tc.c_lflag &= ~(ICANON | ECHO);
tc.c_cc[VMIN] = 0;
tc.c_cc[VTIME] = 0;
tcsetattr(0, TCSANOW, &tc);
}
int main() {
struct pollfd pfd = { .fd = 0, .events = POLLIN };
set_term_quiet_input();
while (1) {
if (poll(&pfd, 1, 0)>0) {
int c = getchar();
printf("Key pressed: %c \n", c);
if (c=='q') break;
}
usleep(1000); // Some work
}
}
'콘솔 IO'가 무슨 뜻인지 완전히 확실하지 않습니다. STDIN에서 읽으시나요, 아니면 다른 소스에서 읽는 콘솔 애플리케이션인가요?
STDIN에서 읽는 경우에는 fread()를 건너뛰고 read()와 write()를 사용하고 poll()을 사용하거나 select()를 선택하여 통화를 차단하지 않아야 합니다.fread가 setbuf()로 EOF를 반환해야 하는 입력 버퍼링을 비활성화할 수 있지만, 저는 그것을 시도해 본 적이 없습니다.
언급URL : https://stackoverflow.com/questions/717572/how-do-you-do-non-blocking-console-i-o-on-linux-in-c
'programing' 카테고리의 다른 글
데이터 테이블: 정의되지 않은 속성 'mData'를 읽을 수 없습니다. (0) | 2023.06.06 |
---|---|
진행 대화 상자와 배경 스레드가 활성화되었을 때 화면 방향 변경을 처리하는 방법은 무엇입니까? (0) | 2023.06.06 |
django 2.0의 경우 urls.py 의 path() 또는 url() 중 어느 것을 사용하는 것이 더 좋습니까? (0) | 2023.06.06 |
장고-고-고-고-고-고-고-고-고가 나타나지 않음 (0) | 2023.06.06 |
S3 버킷의 하위 폴더 이름을 bo에서 3으로 검색하는 중 (0) | 2023.06.06 |