首先是用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]);
}