使用pthreads偷看stdin [英] Peek stdin using pthreads

查看:161
本文介绍了使用pthreads偷看stdin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想偷看stdin,看看有没有使用pthreads。我(认为我)需要这样做,因为如果在std中没有什么,流访问功能将阻塞输入。

I'm trying to peek stdin to see if anything is there using pthreads. I (think I) need to do this because if there is nothing in std in, stream access functions will block for input.

我觉得这样做的方法是触发一个检查stdin的pthread,然后sleep(1)查看线程是否发现了任何东西。

I feel the way to do this is to fire off a pthread that checks stdin, and sleep(1) and see if the thread found anything.

这里是我到目前为止。如果没有任何东西进入程序,那么它将如预期的那样休眠,但如果stdin中的某些东西在线程中不会被触发。

Here's what I have so far. If nothing is piped into the program then it will sleep as expected, but if something is in stdin the thread never gets fired.

#include <iostream>
#include <pthread.h>
#include <stdlib.h>

using namespace std;

void *checkStdIn(void *d){
    char c = '\0';
    c = cin.peek();
    if (c){
        cout << c << endl;
    }
}

int main(int argc, char *argv[]){

    pthread_t thread;
    int rc;
    rc = pthread_create(&thread, NULL, checkStdIn, NULL);
    if (rc){
        cerr << "Error no. " << rc << endl;
        exit(EXIT_FAILURE);
    }
    sleep(2); 

    return 0;
}    


推荐答案

您不需要pthread为此,你可以使用 select(2) poll(2)知道如果你可以偷看stdin没有阻止您的应用程序。为此,我编写了 my_peek()函数,你只需要传递你想等待的输入秒数(如果你不需要传递0想要等待):

You don't need pthreads for that and you can use select(2) or poll(2) to known if you can peek the stdin without blocking your application. For that I coded the my_peek() function which you just need to pass the number of seconds you want to wait for the input (you can even pass 0 if you don't want to wait):

/* According to POSIX.1-2001 */
#include <sys/select.h>

/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <iostream>

int
my_peek(unsigned int nsecs)
{
    struct timeval timeout;
    fd_set rfds;
    int fd;

    // stdin file descriptor is 0
    fd = 0;

    timeout.tv_sec = nsecs;
    timeout.tv_usec = 0;

    FD_ZERO(&rfds);
    FD_SET(fd, &rfds);

    if (select(fd + 1, &rfds, NULL, NULL, &timeout) > 0)
        return std::cin.peek();
    return -1;
}

int
main(void)
{
    int peek;

    peek = my_peek(2);
    if (peek != -1) {
        std::cout << "we could peek without freezing" << std::endl;
        std::cout << "my_peek() returned " << peek << std::endl;
    } else {
        std::cout << "we could not peek without freezing" << std::endl;
    }

    return 0;
}

请注意,依赖 select (2)来判断 cin 对象或 stdin FILE 结构,因为,如Nemo所说,它们是BUFFERED。最好的做法是在这个例子中使用 read(2)避免cin。改进版本的 my_peek()如下所示:

Please note that it is BAD to rely on select(2) to tell if there is data in the cin object or stdin FILE structure because, as Nemo stated, they are BUFFERED. The best thing to do is avoid "cin" in this example using read(2). The improved version of my_peek() would look like:

int
my_peek(unsigned int nsecs)
{
    struct timeval timeout;
    fd_set rfds;
    int fd;
    unsigned char c;

    // stdin file descriptor is 0
    fd = 0;

    timeout.tv_sec = nsecs;
    timeout.tv_usec = 0;

    FD_ZERO(&rfds);
    FD_SET(fd, &rfds);

    if (select(fd + 1, &rfds, NULL, NULL, &timeout) <= 0)
        return -1;
    if (read(fd, &c, 1) != 1)
        return -1;
    return static_cast<int>(c); /* or "return (int)c" for C-only programs */
}

有关更多信息,请检查 选择(2) nofollow> http://linux.die.net/man/2/select

For more information please check the select(2) manual page at http://linux.die.net/man/2/select.

PS:您可以尝试依赖返回的值通过cpluplus网站 std :: cin.rdbuf() - > in_avail() reference / iostream / streambuf / in_avail /rel =nofollow> http://www.cplusplus.com/reference/iostream/streambuf/in_avail/ ,甚至在 readsome )方法,但它们通常依赖于 FILE 缓冲区,它是 istream 不在GNU C ++库中公开。不要这样做,否则可能会失败。

PS: You could try to rely on the value returned by the std::cin.rdbuf()->in_avail() as explained in the cpluplus site http://www.cplusplus.com/reference/iostream/streambuf/in_avail/, or even in the readsome() method of the istream class, but they usually depend on the FILE buffer which is not exposed in the GNU C++ library. Don't do it or you might fail.

这篇关于使用pthreads偷看stdin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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