Linux_5.3_线程同步


pthread_cond_init 函数原型:

pthread_cond_init 初始化条件变量

所需头文件

#include <pthread.h>

函数说明

初始化一个条件变量

函数原型

int pthread_cond_init(pthread_cond_t *restrict cond, 

                                    const pthread_condattr_t *restrict attr)

函数传入值

cond

指向要初始化的条件变量的指针


attr

当参数attr为空指针时,函数创建的是一个缺省的条件变量。否则条件变量的属性将由attr中的属性值来决定。



函数返回值

成功:0

出错:返回错误码


错误代码

EAGAIN:系统缺少足够的资源去初始化其他的互斥量

ENOMEM:内存不足去初始化条件变量

EBUSY:实施检测尝试初始化cond所引用的对象,以前初始化,但尚未销毁的,条件变量。

EINVAL:attr所指定的值无效


pthread_cond_destroy 函数原型:

  pthread_cond_destroy 释放条件变量

所需头文件

#include <pthread.h>

函数说明

 释放条件变量

函数原型

 int pthread_cond_destroy(pthread_cont_t *cond)

函数传入值

   cont 

要释放的条件变量的参数





函数返回值

成功:返回0

失败:返回错误码

错误代码

EBUSY:检测到企图摧毁被锁定的通过cond属性引用的目标 或者 被另一线程引用

EINVAL: cond所指定的值失效



pthread_cond_signal函数原型:

  pthread_cond_signal 发送一个条件变量

所需头文件

#include <pthread.h>

函数说明

 用来释放被阻塞在指定条件变量上的一个线程。

函数原型

 int pthread_cond_signal(pthread_cont_t *cond)

函数传入值

   cont 

要释放的条件变量的参数





函数返回值

成功:返回0

失败:返回错误码

错误代码

EINVAL: cond值并不是参照一个初始化条件变量




pthread_cond_ broadcast函数原型:

  pthread_cond_broadcast广播一个条件变量

所需头文件

#include <pthread.h>

函数说明

 释放阻塞的所有线程

函数原型

 int pthread_cond_broadcast(pthread_cont_t *cond)

函数传入值

   cont 

要释放的条件变量的参数





函数返回值

成功:返回0

失败:返回错误码

错误代码

EINVAL: cond值并不是参照一个初始化条件变量



pthread_cond_ wait函数原型:

  pthread_cond_wait 阻塞当前线程

所需头文件

#include <pthread.h>

函数说明

 用于阻塞当前线程

函数原型

 int pthread_cond_wait(pthread_cont_t *cond
pthread_mutex_t *restrict mutex)

函数传入值

   cond

指定堵塞的条件变量参数


mutex

指定堵塞的互斥量



函数返回值

成功:返回0

失败:返回错误码

错误代码

EINVAL:cond,mutex,abstime所指定的值无效
EINVAL:不同的互斥量在相同的条件变量下为pthread_cond_timedwait或者

               pthread_cond_wait函数提供并发操作
EPERM:没有由当前线程被调用时的互斥量




pthread_cond_ timedwait函数原型:

pthread_cond_ timedwait 创建一个新线程

所需头文件

#include <pthread.h>

函数说明

在函数调用时创建一个新线程

函数原型

int pthread_timedwait(pthread_cond_t *restrict cond,

pthread_mutex_t *restrict mutex

const struct timespec *restrict abstime);

函数传入值

cond     

指定堵塞的条件变量参数


mutex

指定堵塞的互斥量

abstime       

指定堵塞的绝对时间





函数返回值

成功:0

错误:返回错误码

错误代码

ETIMEDOUT:abstime指定的时间在pthread_timedwait中已经执行完毕

EINVAL:cond,mutex,abstime所指定的值无效
EINVAL:不同的互斥量在相同的条件变量下为pthread_cond_timedwait或者

               pthread_cond_wait函数提供并发操作
EPERM:没有由当前线程被调用时的互斥量





更多详解



pthread_cond_wait()  用于阻塞当前线程,等待别的线程使用 pthread_cond_signal() pthread_cond_broadcast来唤醒它  pthread_cond_wait()   必须与pthread_mutex 配套使用。 pthread_cond_wait() 函数一进入wait状态就会自动release mutex。当其他线程通过 pthread_cond_signal() pthread_cond_broadcast ,把该线程唤醒,使 pthread_cond_wait()通过(返回)时,该线程又自动获得该 mutex
   pthread_cond_signal 函数的作用是发送一个信号给另外一个正在处于阻塞等待状态的线程,使其脱离阻塞状态,继续执行.如果没有线程处在阻塞等待状态,pthread_cond_signal也会成功返回。
  使用pthread_cond_signal一般不会有“惊群现象”产生,他最多只给一个线程发信号。假如有多个线程正在阻塞等待着这个条件变量的话,那么是根据各等待线程优先级的高低确定哪个线程接收到信号开始继续执行。如果各线程优先级相同,则根据等待时间的长短来确定哪个线程获得信号。但无论如何一个pthread_cond_signal调用最多发信一次。
   但是 pthread_cond_signal 在多处理器上可能同时唤醒多个线程,当你只能让一个线程处理某个任务时,其它被唤醒的线程就需要继续 wait,而且规范要求 pthread_cond_signal 至少唤醒一个pthread_cond_wait上的线程,其实有些实现为了简单在单处理器上也会唤醒多个线程. 
   另外,某些应用,如线程池, pthread_cond_broadcast 唤醒全部线程,但我们通常只需要一部分线程去做执行任务,所以其它的线程需要继续wait.所以强烈推荐对pthread_cond_wait() 使用while循环来做条件判断.

详细解释请看:

http://blog.csdn.net/hudashi/article/details/7709421


实例一:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>


#define BUFFER_SIZE 8


struct Products
{
    int buffer[BUFFER_SIZE];
    /*Atomicity mutually for guaranteed access operations */
    pthread_mutex_t locker;
    /*Is readable*/
    pthread_cond_t notEmpty;
    /*Is writable*/
    pthread_cond_t notFull;
    int posReadFrom;
    int posWriteTo;
};


/*Buffer is full*/
int BufferIsFull(struct Products* products)
{
    if((products->posWriteTo + 1)%BUFFER_SIZE == products->posReadFrom)

 {
        return 1;
    }
    return 0;
}
/*Buffer is empty*/
int BufferIsEmpty(struct Products* products)
{
    if((products->posWriteTo)%BUFFER_SIZE == products->posReadFrom)
    {
        return 1;
    }
    return 0;
}


/*manufactured products*/
void Produce(struct Products *products,int item)
{
    /*Atomic operation*/
    pthread_mutex_lock(&products->locker);
    while(BufferIsFull(products))

{
        pthread_cond_wait(&products->notFull,&products->locker);
    }


    /*write data*/
    products->buffer[products->posWriteTo] = item;
    products->posWriteTo++;


    if(products->posWriteTo >= BUFFER_SIZE);
    {
        products->posWriteTo = 0;
    }


    /*send signal*/
    pthread_cond_signal(&products->notEmpty);
    printf("item: %d\n",item);
//  sleep(1);
    /*unlock*/
    pthread_mutex_unlock(&products->locker);
}
/*consume*/
int Consume(struct Products *products)

{
    int item;
    pthread_mutex_lock(&products->locker);
    /*waiting for time,not data*/
    while(BufferIsEmpty(products))
    {
        pthread_cond_wait(&products->notEmpty,&products->locker);
    }


    /*Extracting data*/
    item = products->buffer[products->posReadFrom];
    products->posReadFrom++;
    /*If read the end ,then from the beginning*/
    if(products->posReadFrom >= BUFFER_SIZE)
    {
        products->posReadFrom = 0;
    }


    pthread_cond_signal(&products->notFull);
    pthread_mutex_unlock(&products->locker);


    return item;
}

#define END_FLAG (-1)


struct Products products;


void *ProducerThread(void *data)
{
    int i;
    for(i=0;i<16;++i)
    {
        printf("producer: %d\n",i);
        Produce(&products,i);
//      sleep(1);
    }
    Produce(&products,END_FLAG);
    return NULL;
}


void *ConsumerThread(void *data)
{
    int item;
    while(1)
    {
        item = Consume(&products);
        if(END_FLAG == item)

 {
            break;
        }


        printf("consumer: %d\n",item);
    }
    return (NULL);
}




int main(int argc, char* argv[])
{


    pthread_t producer;
    pthread_t consumer;
    int result;


    pthread_create(&producer,NULL,&ProducerThread,NULL);
    pthread_create(&consumer,NULL,&ConsumerThread,NULL);


    sleep(2);


    pthread_join(producer,(void *)&result);

   pthread_join(consumer,(void *)&result);


    exit(EXIT_SUCCESS);

}

实例二:

pthread_cond_broadcast的使用:
#include <pthread.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <unistd.h>  
#include <string.h>  
pthread_mutex_t mymutex1 = PTHREAD_MUTEX_INITIALIZER;  
/*pthread_mutex_t mymutex2 = PTHREAD_MUTEX_INITIALIZER;  */
pthread_cond_t mycond = PTHREAD_COND_INITIALIZER;  
void *mythread1(void *param)  
{  
    printf("begin mythread1.\n");  
    pthread_mutex_lock(&mymutex1);  
    printf("wait in mythread1.\n");  
    pthread_cond_wait(&mycond,&mymutex1);  
    pthread_mutex_unlock(&mymutex1);  
    printf("end mythread1.\n");  
    return NULL;  
}  
void *mythread2(void *param)  
{  
    printf("begin mythread2.\n");  
    pthread_mutex_lock(&mymutex1);  
    printf("wait in mythread2.\n");  
    pthread_cond_wait(&mycond,&mymutex1);  
    pthread_mutex_unlock(&mymutex1);  
    printf("end mythread2.\n");  
    return NULL;  
}  
int main(void)  
{  
    printf("begin main thread.\n");  
    int i;  
    pthread_t tid1,tid2;  
    pthread_create(&tid1,NULL,mythread1,NULL);  
    pthread_create(&tid2,NULL,mythread2,NULL);  
    sleep(2);  
    printf("try to wake up mythread1 and mythread2 in main thread.\n");  
    if(pthread_cond_broadcast(&mycond)){  
        printf("error\n");  
        return 1;  
    }  
    void *res;  
    pthread_join(tid1, &res);  
    pthread_join(tid2, &res);  
    printf("end main thread.\n");  
    return 0;  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值