linux pthread_cond_timedwait() 线程同步

本文介绍了Linux中使用pthread_cond_timedwait()进行线程同步的方法,包括线程的等待与通知,以及需要注意的问题。线程通过该函数等待cond条件变量的signal,超时会返回。当多个线程等待同一条件变量时,pthread_cond_broadcast()可唤醒所有线程。同时,文章提到了线程属性设置和相关参考书籍。

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值