我正在用 C 為 Linux 撰寫一個程式。我打算popen()用來運行另一個程式。在我等待該程式完成時,我希望能夠檢測用戶是否按下鍵盤上的鍵,以便我知道他們是要繼續處理他們的檔案還是要在pclose(). 實作這一目標的最佳方法是什么?
uj5u.com熱心網友回復:
您可以使用執行緒在呼叫之前等待鍵popen、呼叫popen、取消執行緒并檢查在呼叫之前是否按下了任何鍵pclose。
一個使用 C 的示例(將它改編為 C 很簡單),為了簡潔起見,我省略了錯誤檢查:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *handler(void *arg)
{
int *key = arg;
char c;
while (read(STDIN_FILENO, &c, 1))
{
if (*key == 0)
{
*key = c;
}
}
return NULL;
}
int main(void)
{
pthread_t thread;
int key = 0;
pthread_create(&thread, NULL, handler, &key);
// Simulate a long read using sleep 5
// to give you enough time to press a key enter
FILE *cmd = popen("sleep 5; echo 'command finished'", "r");
char str[1024];
while (fgets(str, sizeof str, cmd))
{
printf("%s", str);
}
pthread_cancel(thread);
pthread_join(thread, NULL);
if (key != 0)
{
printf("%c was pressed\n", key);
}
pclose(cmd);
return 0;
}
編輯:
有人在評論中建議使用select而不是pthreads,我認為使用沒有太大的優勢,select但我們繼續:
select()允許等待檔案描述符(在這種情況下stdin)準備好,它可以連接到一個超時,該超時指定select()應該阻止等待檔案描述符準備好的時間間隔,在這種情況下,因為我們想要read掛起的內容stdin一旦popen完成,我們將超時設定為0時,我們需要干凈的結束stdin,否則我們最終如果用戶開始打字,但不會按回車,或型別的多個數字按ENTER鍵poluting垃圾的終端。
在這種情況下,恕我直言,執行緒是一種更清潔的選擇。使用相同的方法select:
#define _XOPEN_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <termios.h>
void clear_stdin(void)
{
int stdin_copy = dup(STDIN_FILENO);
tcdrain(stdin_copy);
tcflush(stdin_copy, TCIFLUSH);
close(stdin_copy);
}
int keypress(int state)
{
int key = 0;
// state 0 = timeout (nothing to get)
if (state == 1)
{
char c;
if (read(STDIN_FILENO, &c, 1))
{
key = c;
}
}
clear_stdin();
return key;
}
int main(void)
{
fd_set set;
FD_ZERO(&set);
FD_SET(STDIN_FILENO, &set);
FILE *cmd = popen("sleep 5; echo 'command finished'", "r");
char str[1024];
while (fgets(str, sizeof str, cmd))
{
printf("%s", str);
}
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
int state = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
int key = keypress(state);
if (key != 0)
{
printf("%c was pressed\n", key);
}
pclose(cmd);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/348805.html
上一篇:CentOSPythonDockerfile影像大小減少
下一篇:LIBS環境變數的語法是什么?
