1 线程的等待与通知
线程的异步通知机制。一个线程正在等待某件事件的发生(在阻塞),另外一个线程触发一个信号,通知这个线程继续往下运行。请参考如下的程序段,
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <stdio.h>
#include <limits.h> //PTHREAD_STACK_MIN
/**
* @brief gettimeofday() 函数封装一下,主要是怕这个函数不是线程安全
*/
pthread_mutex_t pGetTime = PTHREAD_MUTEX_INITIALIZER;
void gettimeofdayHaxMutex(struct timeval *tv) //主要担心 gettimeofday 并不是线程安全的函数
{
pthread_mutex_lock(&pGetTime);
gettimeofday(tv,NULL);
pthread_mutex_unlock(&pGetTime);
}
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
#if 0
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
#endif
int timedwait_pthread_run()
{
int iReturnCode = 0;
pthread_mutex_lock(&mutex);
struct timespec tsp; //线程睡眠那么长时间,如果有事件,则唤醒这个线程,返回消息
struct timeval now;
gettimeofdayHaxMutex(&now);
tsp.tv_sec = now.tv_sec;
tsp.tv_nsec = now.tv_usec*1000; //nannoseconds
tsp.tv_sec += 10; //10秒
iReturnCode = pthread_cond_timedwait(&cond,&mutex,&tsp);
pthread_mutex_unlock(&mutex);
if ( iReturnCode == ETIMEDOUT )
{
fprintf(stderr,"%s","pthread_cond_timedwait timeout!!\n");
return -1;
}
else if ( (iReturnCode == EINVAL) || (iReturnCode == EINVAL) )
{
fprintf(stderr,"%s","pthread_cond_timedwait error!!\n");
return -1;
}
fprintf(stderr,"%s","pthread_cond_timedwait has been signal!!\n");
return 0;
}
void pthread_signal_run()
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond); //send a signal to wait up the pthread_cond_timedwait() thread
pthread_mutex_unlock(&mutex);
}
#define MICHAEL_SET_PTHREAD_STACK_SIZE 64
int main()
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //分离属性
size_t stacksize = MICHAEL_SET_PTHREAD_STACK_SIZE*PTHREAD_STACK_MIN;
pthread_attr_setstacksize(&attr,stacksize); //线程堆栈大小 512K
pthread_t pWaitPthread;
pthread_t pSignalPhread;
pthread_create(&pWaitPthread,&attr,(void *)timedwait_pthread_run,NULL);
sleep(5);
//sleep(10);
pthread_create(&pSignalPhread,&attr,(void *)pthread_signal_run,NULL);
pthread_attr_destroy(&attr);
while(1)
{
sleep(10);
}
return 0;
}int timedwait_pthread_run() 线程阻塞等待在 pthread_cond_timedwait() 这个函数,等待 cond 条件变量的signal 的到来,如果到指定时间还没有等到信号,则超时返回。这个函数具体使用方法请参考 <<Advanced Programming in the Unix Environment>>。
void pthread_signal_run() 线程函数发送一个信号,正等待在 cond 条件变量的线程得到这个信号后,继续往下运行。
2 需要注意问题
- 一个 mutex 对应多个 cond 是可以的,因为pthread_cond_wait() 这个函数调用,第一步就是 对mutex解锁。但是,使用多个 mutex 对应一个 cond,行为未定义。 详情请参考 <<Using the linux pthread>> 这本书。
- 多个线程同时等在一个 cond 条件变量上时,可用 pthread_cond_broadcast() 唤醒所有阻塞在这个条件变量的线程
使用 pthread_create() 创建一个线程,默认属性为非分离,非绑定,默认的线程堆栈为 10M,与父进程同样的优先级。pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED) 函数设置线程的分离属性,线程退出时,由系统回收资源。
3 参考书籍
<<Advanced Linux Programming>> 比 <<Advanced Programming in the Unix Environment>> 基础一点
<<Advanced Programming in the Unix Environment>> 简称APUE
本文介绍了Linux中使用pthread_cond_timedwait()进行线程同步的方法,包括线程的等待与通知,以及需要注意的问题。线程通过该函数等待cond条件变量的signal,超时会返回。当多个线程等待同一条件变量时,pthread_cond_broadcast()可唤醒所有线程。同时,文章提到了线程属性设置和相关参考书籍。

390

被折叠的 条评论
为什么被折叠?



