取消的getchar() [英] Cancelling getchar()

查看:150
本文介绍了取消的getchar()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小的程序,做大量的处理。其中,你可以通过敲击回车键得到的打印的进展。

I've got a small program that does a large amount of processing. The progress of which you can get a print of by hitting the enter key.

我实现这一点的方法是通过在主线程中完成的,而我有一个不断pthread的循环上的getchar的处理()等待回车键。

The way I've implemented this is by having the processing done in the main thread whilst I have a pthread constantly looping on getchar() to wait for the enter key.

问题是,当我与加工完成。当发生这种情况,主线程结束,但仍在等待进入被pssed因为getchar函数()阻止$ P $。

The problem is when I have finished with the processing. When this happens the main thread finishes, but still waits for enter to be pressed because getchar() is blocking.

我如何取消的getchar()?

How do I "cancel" getchar()?

推荐答案

最轻便的解决方案,我能想到的是:

The most portable solution I can think of is:


  • 使用管道()来构造两个文件描述符,一个阅读器和其他作家。给读者以你的阅读()循环;给作家谁需要终止读卡器。

  • 使用选择()从读线程等待为标准输入和读取器管道的可读性。

  • 如果标准输入变得可读,读一个字符,处理它,然后重新启动循环。

  • 如果读者管道变得可读,关闭并终止循环。

  • Use pipe() to construct two FDs, one a reader and the other a writer. Give the reader to your read() loop; give the writer to whoever needs to terminate the reader.
  • Use select() from the read thread to wait for readability of both stdin and the reader pipe.
  • If stdin becomes readable, read a character, process it, and then restart the loop.
  • If the reader pipe becomes readable, close it and terminate the loop.

现在,你应该做的是关闭管道的另一端,这将唤醒读线程走出了选择()键,那么它应该终止。

Now, all you should have to do is close the other end of the pipe and this will wake up the reader thread out of its select() and it should then terminate.

传统的方法包括使用信号,然而,这种基于管道解决方案,可以让你检查输入标准输入和检查,如果你要终止使用相同的轮询机制。

The traditional approach involves using signals, however this pipe-based solution allows you to check for input on stdin as well as check if you should terminate using the same polling mechanism.

需要注意的是混合的getchar()选择()将无法工作,因为的getchar()将有效地使用 FREAD() FREAD进行缓冲()引擎盖下,和可引起选择()来阻止即使有可用的数据。使用阅读()来代替。下面是我用来测试这种方法的示例程序。

Note that mixing getchar() and select() will not work, since getchar() will effectively use fread() under the hood, and the buffering performed by fread() can cause select() to block even though there is data available. Use read() instead. Here is an example program I used to test this approach.

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/select.h>

void * entry_point(void * p) {
    int readpipe = *(int *)p;
    fd_set rfds;

    char c;

    for (;;) {
        FD_ZERO(&rfds);
        FD_SET(STDIN_FILENO, &rfds);
        FD_SET(readpipe, &rfds);

        while (select(readpipe + 1, &rfds, NULL, NULL, NULL) == 0);

        if (FD_ISSET(readpipe, &rfds)) {
            close(readpipe);
            break;
        }

        if (FD_ISSET(STDIN_FILENO, &rfds)) {
            if (read(STDIN_FILENO, &c, sizeof(c)) > 0) {
                printf("Read: %d\n", c);
            }
        }
    }

    printf("Thread terminating\n");

    pthread_exit(NULL);
}

int main() {
    pthread_t thread;
    int r;
    int pipes[2];

    pipe(pipes);

    if (r = pthread_create(&thread, NULL, entry_point, &pipes[0])) {
        printf("Error: %d\n", r);
        return 1;
    }

    sleep(5);

    printf("Closing pipe and joining thread.\n");

    close(pipes[1]);
    pthread_join(thread, NULL);

    pthread_exit(NULL);
}

运行示例:

$ time ./test
1
Read: 49
Read: 10
2
Read: 50
Read: 10
3
Read: 51
Read: 10
4
Read: 52
Read: 10
5
Read: 53
Read: 10
Closing pipe and joining thread.
Thread terminating

real    0m5.004s
user    0m0.004s
sys     0m0.000s

这篇关于取消的getchar()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆