#include <pthread.h>#include <stdio.h>#include <stdlib.h>pthread_cond_t cond_1= PTHREAD_COND_INITIALIZER;/*初始化條件變數*/pthread_cond_t cond_2= PTHREAD_COND_INITIALIZER;/*初始化條件變數*/pthread_cond_t cond_3= PTHREAD_COND_INITIALIZER;/*初始化條件變數*/pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥鎖*/void *thread1(void *);void *thread2(void *);void *thread3(void *);int main(int argc,char** argv){ pthread_t t_a; pthread_t t_b; pthread_t t_c; pthread_create(&t_a,NULL,thread1,(void *)NULL); pthread_create(&t_b,NULL,thread2,(void *)NULL); pthread_create(&t_c,NULL,thread3,(void *)NULL); /*wait "thread1 wait cond_3",or signal maybe lost.*/ sleep(1); pthread_cond_signal(&cond_3); pthread_join(t_a, NULL); pthread_join(t_b, NULL); pthread_join(t_c, NULL); pthread_cond_destroy(&cond_1); pthread_cond_destroy(&cond_2); pthread_cond_destroy(&cond_3); pthread_mutex_destroy(&mutex); exit(0);}void *thread1(void *junk){ while(0x20130306) { pthread_mutex_lock(&mutex); // printf("A waitting cond_3.\n"); pthread_cond_wait(&cond_3,&mutex); printf("AAA\n"); pthread_cond_signal(&cond_1); // printf("A mit cond_1.\n"); pthread_mutex_unlock(&mutex); sleep(1); }}void *thread2(void *junk){ sleep(1); while(0x20130306) { pthread_mutex_lock(&mutex); // printf("B waitting cond_1.\n"); pthread_cond_wait(&cond_1,&mutex); printf("BBB\n"); pthread_cond_signal(&cond_2); // printf("B mit cond_2.\n"); pthread_mutex_unlock(&mutex); sleep(1); }}void *thread3(void *junk){ sleep(1); while(0x20130306) { pthread_mutex_lock(&mutex); // printf("C waitting cond_2.\n"); pthread_cond_wait(&cond_2,&mutex); printf("CCC\n"); pthread_mutex_unlock(&mutex); /*wait "thread1 wait cond_3",or signal maybe lost.*/ sleep(1); pthread_cond_signal(&cond_3); // printf("C mit cond_3.\n"); }}
上面是三個線程順序列印ABC的例子,
用pthread_cond_wait+pthread_cond_signal的機制有個問題,就是當沒人等待你的訊號時,你發的訊號就會丟失。
下面是用管道實現的版本:
#include "hx_pipe.h"#define HX_PIPE_MSG "w"int hx_pipe_init(hx_pipe_t* pp, void* arg){int ret = -1;if ( NULL == pp )return ret;ret = pipe(pp->pipe);return ret;}int hx_pipe_write(hx_pipe_t* pp){if ( NULL == pp )return -1;int ret = 0;ret = write(pp->pipe[HX_PIPE_ROLE_WRITE], \HX_PIPE_MSG, sizeof(HX_PIPE_MSG));if ( ret > 0 )return 0;elsereturn -1;}int hx_pipe_read(hx_pipe_t* pp){if ( NULL == pp )return -1;int ret = -1;int buf[256];ret = read(pp->pipe[HX_PIPE_ROLE_READ], \buf, sizeof(buf));if ( ret > 0 )return 0;elsereturn -1;}int hx_pipe_readtimeout(hx_pipe_t* pp, int sec, int usec){if ( NULL == pp )return -1;int ret = -1;int fd = pp->pipe[HX_PIPE_ROLE_READ];int buf[256];fd_set rfd;struct timeval tv;memset(&tv, 0, sizeof(tv));tv.tv_sec = sec;tv.tv_usec = usec;FD_ZERO(&rfd);FD_SET(fd, &rfd);ret = select(fd+1, &rfd, NULL, NULL, &tv);if ( 1 == ret ){read(fd, buf, sizeof(buf));}return ret;}void hx_pipe_destroy(hx_pipe_t * pp){if ( pp ){close(pp->pipe[0]);close(pp->pipe[1]);}}void* func_threada(void * junk);void* func_threadb(void * junk);static hx_pipe_t g_pipe_0;static hx_pipe_t g_pipe_1;static hx_pipe_t g_pipe_2;static int i=0;void* func_threada(void *junk){while(0x20130306){//printf("thread_a: i=%d\n",i++);hx_pipe_write(&g_pipe_0);printf("thread_a sleep.\n");hx_pipe_read(&g_pipe_2);sleep(1);}}void* func_threadb(void* junk){sleep(1);while(0x20130306){//printf("thread_b: i=%d\n",i++ );hx_pipe_read(&g_pipe_0);printf("thread_b sleep.\n");hx_pipe_write(&g_pipe_1);sleep(1);}}void* func_threadc(void* junk){sleep(1);while(0x20130306){//printf("thread_c: i=%d\n",i++ );hx_pipe_read(&g_pipe_1);printf("thread_c sleep.\n");hx_pipe_write(&g_pipe_2);sleep(1);}}int main(int argc,char** argv){pthread_t threada;pthread_t threadb;pthread_t threadc;if (hx_pipe_init(&g_pipe_0,NULL)){goto pipe_init_fail;}if (hx_pipe_init(&g_pipe_1,NULL)){goto pipe_init_fail;}if (hx_pipe_init(&g_pipe_2,NULL)){goto pipe_init_fail;}pthread_create(&threada,NULL,func_threada,(void*)NULL);pthread_create(&threadb,NULL,func_threadb,(void*)NULL);pthread_create(&threadc,NULL,func_threadc,(void*)NULL);pthread_join(threada,NULL);pthread_join(threadb,NULL);pthread_join(threadc,NULL);exit(0);pipe_init_fail:return -1;}