多线程+管道的用法

最近在做一个线程池写磁盘文件的任务。主线程通过管道向线程池写任务,线程池从管道的读端读任务。

按UNIX环境高级编程说的,我在主线程中关闭了管道的读端,在线程池的初始化时关闭了写端。

但是,在这种情况下,没法正常工作,只有在不关闭管道的读和写端的时候才能正常工作。

原来书上讲的是在进程的情况下,而不是我所用的线程,子线程是和创建它的进程共享fd的,任何一方关闭管道的读或写都会影响到另一方。



还有一个问题需要说明的是,管道(阻塞的读和写)写满之后,会阻塞到写端;

只有读端把管道读空(我的机器上的管道长度是4K)之后才能继续写管道,我以前以为是,只要读端读了一个字节,写端就可以继续写。

还有是:我一开始疯狂的写管道,可以写64K而不是机器上的标识(我用ulimit -p查看到是4K)4K。这个我也不知道是怎么回事儿。

代码如下:

#include    "my.h"

void * listen_thread(void *arg);
static void sig_usr(int signo);
static void sig_pipe(int signo);
int pipe_fd_work[2];
 
int main(int argc, char** argv)
{
    if (pipe(pipe_fd_work) < 0)
    {
        cerr<<"open pipe_fd_work error:"<<strerror(errno)<<endl;
        return -1;
    }
    else
    {
        //if i close this read of pipe ,thread can't read it
        //because they share the same fd
        //close(pipe_fd_work[0]);
    }

    signal(SIGINT, sig_usr);
    pthread_t listen_pid;
    pthread_create(&listen_pid, NULL, listen_thread, NULL);

    int nwrited;
    char *writebuf = new char[1024];
    setnonblock(pipe_fd_work[1]);
    while(1)
    {
        cout<<"before write\n"<<endl;
        
        nwrited = write(pipe_fd_work[1], writebuf, 1024);
        cout<<"after write\n"<<endl;
        if (nwrited == -1)
        {
            cerr<<"write pipe error:"<<strerror(errno)<<endl;
        }
        else
        {
            cout<<"writen:"<<nwrited<<endl;
        }
    }

    pthread_join(listen_pid, NULL);

    return 0;
}

void * listen_thread(void *arg)
{
    char *buf = new char[2048];
    int nreaded;
    while(1)
    {
        nreaded = read(pipe_fd_work[0], buf, 2048);
        if (nreaded == -1)
            break;
        else
        {
            cout<<"readed:"<<nreaded<<endl;
        }
        sleep(10);
    }
    delete [] buf;
    buf = NULL;
    signal(SIGPIPE, sig_pipe);
}

static void sig_pipe(int signo)
{
    if (signo == SIGPIPE)
    {
        cout<<"progrom exit"<<endl;
        exit(1);
    }
}

static void sig_usr(int signo)
{
    if (signo == SIGINT)
    {
        cout<<"progrom exit"<<endl;
        exit(1);
    }
}


你可能感兴趣的:(thread,多线程,null,delete,任务,Signal)