linux下线程之间pipe通信c++练习

1 篇文章 0 订阅

 首先是用pipe在主线程和子线程通信,而且read是阻塞的

#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

typedef struct __Thread
{
    pthread_t tid;                 //thread id
    int notifyReceiveFd;           //the receive side of pipe
    int notifySendFd;              //the send side pf pipe
} Thread;

Thread* m_thread;

void* work_thread(void* argc)
{
    Thread* param=(Thread*) argc;
    printf("childthread_id=%lu\n",param->tid);
    int contant=0;
    printf("childthread--read return %ld\n",read(param->notifyReceiveFd, &contant, sizeof(int)));
    printf("childthread--read from pipe %d\n", contant);

    sleep(5);
    contant=100;
    //printf("childthread--write return %ld\n", write(param->notifySendFd, &contant, sizeof(int)));

}

int main(int argc, char** argv)
{
    //build pipe between main-thread and child-thread
    m_thread = new Thread;
    int fds[2];
    if(pipe(fds))
    {
        perror("create pipe fds_1 error\n");
    }

    int fds_1[2];
    if(pipe(fds_1))
    {
        perror("create pipe fds_1 error\n");
    }

    m_thread->notifyReceiveFd=fds[0];
    m_thread->notifySendFd=fds_1[1];

    pthread_t id;


    pthread_create(&(m_thread->tid),NULL,work_thread,(void*)m_thread);
    printf("mainthread--childthread id is %lu\n",m_thread->tid);

    int contant = 1;

    printf("mainthread--write %d to pipe\n",contant);
    printf("mainthread--write return %ld\n", write(fds[1], &contant, sizeof(int)));

    //下面的read()函数会阻塞,因为没有给fds_1管道写入数据(把work_thread中注释掉的write那行去掉注释,则read()就可以读到数据而不阻塞)
    printf("mainthread--read return %ld\n", read(fds_1[0], &contant, sizeof(int)));

    printf("mainthread--read from pipe %d\n", contant);
    pthread_join(m_thread->tid,NULL);
    close(fds[0]);
    close(fds[1]);
    close(fds_1[0]);
    close(fds_1[1]);
}

 上面的代码会被阻塞,若要不阻塞运行,则要把文件描述符设置为非阻塞的,则read会立即返回(当管道没有数据可读时返回-1)

    
    fcntl(fds_1[0], F_SETFL, O_NONBLOCK);
    //在read前,用fcnl设置fds_1[0]为非阻塞的
    printf("mainthread--read return %ld\n", read(fds_1[0], &contant, sizeof(int)));

如要设置超时,可以使用select或poll,下面代码只举例select。更多相关知识可以参考这篇文章

#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

typedef struct __Thread
{
    pthread_t tid;                 //thread id
    int notifyReceiveFd;           //the receive side of pipe
    int notifySendFd;              //the send side pf pipe
} Thread;

Thread* m_thread;

void* work_thread(void* argc)
{
    Thread* param=(Thread*) argc;
    printf("childthread_id=%lu\n",param->tid);
    int contant=0;
    printf("childthread--read return %ld\n",read(param->notifyReceiveFd, &contant, sizeof(int)));
    printf("childthread--read from pipe %d\n", contant);


    sleep(5);
    contant=100;
    //printf("childthread--write return %ld\n", write(param->notifySendFd, &contant, sizeof(int)));

}

int main(int argc, char** argv)
{
    //build pipe between main-thread and child-thread
    m_thread = new Thread;
    int fds[2];
    if(pipe(fds))
    {
        perror("create pipe fds_1 error\n");
    }

    int fds_1[2];
    if(pipe(fds_1))
    {
        perror("create pipe fds_1 error\n");
    }

    m_thread->notifyReceiveFd=fds[0];
    m_thread->notifySendFd=fds_1[1];

    pthread_t id;


    pthread_create(&(m_thread->tid),NULL,work_thread,(void*)m_thread);
    printf("mainthread--childthread id is %lu\n",m_thread->tid);

    int contant = 1;

    printf("mainthread--write %d to pipe\n",contant);
    printf("mainthread--write return %ld\n", write(fds[1], &contant, sizeof(int)));

    fd_set m_fds;
    FD_ZERO(&m_fds);
    FD_SET(fds_1[0], &m_fds);
    struct timeval t = {10, 0};
    select(fds_1[0] + 1, &m_fds, NULL, NULL, &t);
//若10后内fds_1[0]不可读则停止阻塞,程序继续往下走;如果把work_thread中的write那行去掉注释,
//则注释到write执行完毕,因为我write前sleep了5s,所以我这里会阻塞5s,然后程序继续往下走
    printf("mainthread--read return %ld\n", read(fds_1[0], &contant, sizeof(int)));

    printf("mainthread--read from pipe %d\n", contant);
    pthread_join(m_thread->tid,NULL);
    close(fds[0]);
    close(fds[1]);
    close(fds_1[0]);
    close(fds_1[1]);
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值