#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;
else
return -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;
else
return -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;
}