linux线程同步---条件变量

来源:互联网 发布:煲机软件 编辑:程序博客网 时间:2024/04/30 14:57

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使”条件成立”(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
linux定义一系列函数来操作条件变量,如下:

初始化和反初始化函数:

#include <pthread.h>int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr); //初始化条件变量int pthread_cond_destroy(pthread_cond_t *cond); //销毁条件变量

返回值:若成功,返回0;若出错,返回错误编号
参数:

  • cond:指向结构pthread_cond_t的指针
  • attr:为NULL时, 会创建一个默认属性的条件变量

初始化条件变量有两种方式,一种是静态,另一种是动态
静态态初始化:pthread_cond_t cond = PTHREAD_COND_INITIALIER;
动态初始化:int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

等待函数:

#include <pthread.h>int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restric mutex);int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout);

返回值:若成功,返回0;若出错,返回错误编号
pthread_cond_wait是阻塞等待
pthread_cond_timedwait是阻塞超时等待.

通知函数:

#include <pthread.h>int pthread_cond_signal(pthread_cond_t *cond);int pthread_cond_broadcast(pthread_cond_t *cond);

返回值:若成功,返回0;若出错,返回错误编号
这两个函数相当于发送信号通知等待的条件满足了。pthread_cond_signal用于解除单个线程的阻塞,相当于单播。pthread_cond_broadcast用于解除所有线程的阻塞,相当于多播。

示例程序:

/* cond_mutex.c*/#include <stdio.h>#include <pthread.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <semaphore.h>pthread_mutex_t mutex;  pthread_cond_t cond; static int count = 0 ;#define FILENAME "cond_mutex_save"/*线程一*/void thread1(void * arg){    char write_buf[] = "1";    int fd = *(int *)arg;    printf("this is pthread1,fd = %d\n",fd);    int i = 0;    while(1)    {        pthread_mutex_lock(&mutex);          pthread_cond_wait(&cond, &mutex);          for(i = 0;i<5;i++)        {            if (write(fd,write_buf,sizeof(write_buf)))            {                perror("write");            }            count++;        }        printf("This is a pthread1....and count = %d\n",count);        /*信号量加一,V 操作*/        pthread_mutex_unlock(&mutex);    }}/*线程二*/void thread2(void * arg){    char write_buf[] = "2";    int fd = *(int *)arg;    printf("this is pthread2 and fd = %d\n",fd);    int i = 0;    while(1)    {        pthread_mutex_lock(&mutex);          pthread_cond_wait(&cond, &mutex);         for(i = 0;i<5;i++)        {            if (write(fd,write_buf,sizeof(write_buf)))            {                perror("write");            }                   count++;        }        printf("This is a pthread2.... count = %d\n",count);            pthread_mutex_unlock(&mutex);     }}int main(void){    int fd = open(FILENAME,O_RDWR | O_CREAT,0777);    if(fd < 0)    {        perror("open");    }    printf("open success!\n");    int i,ret;    pthread_mutex_init(&mutex, NULL);      pthread_cond_init(&cond, NULL);     pthread_t id1,id2;    /*创建线程一*/    ret=pthread_create(&id1,NULL,(void *) thread1,&fd);    if(ret!=0){    perror("Create pthread error!\n");    }    /*创建线程二*/    ret=pthread_create(&id2,NULL,(void *) thread2,&fd);    if(ret!=0){    perror ("Create pthread error!\n");    }    while(1)    {          sleep(1);        pthread_cond_signal(&cond);      }    /*等待线程结束*/    pthread_join(id1,NULL);    pthread_join(id2,NULL);    return 0;}

实验结果:

ubuntu:~/test/pthread_test$ gcc cond_mutex.c -o cond_mutex -lpthreadubuntu:~/test/pthread_test$ ./cond_mutexopen success!this is pthread1,fd = 3this is pthread2 and fd = 3write: Successwrite: Successwrite: Successwrite: Successwrite: SuccessThis is a pthread1....and count = 5write: Successwrite: Successwrite: Successwrite: Successwrite: SuccessThis is a pthread2.... count = 10write: Successwrite: Successwrite: Successwrite: Successwrite: SuccessThis is a pthread1....and count = 15write: Successwrite: Successwrite: Successwrite: Successwrite: SuccessThis is a pthread2.... count = 20write: Successwrite: Successwrite: Successwrite: Successwrite: Success

从上面的例子程序中,可以看到,我们在main函数中创建线程一和线程二。然后调用函数pthread_mutex_init(&mutex, NULL)、pthread_cond_init(&cond, NULL) 初始化互斥锁mutex 和条件变量cond。 接着每隔1秒调用函数pthread_cond_signal(&cond) 给线程发送条件变量cond满足的信号。在线程一和线程二,每次向文件 cond_mutex_save 写入数据之前,都会调用pthread_cond_wait(&cond, &mutex) 函数判断条件变量是否满足。如果不满足条件,则继续等待。而且在访问文件之前调用pthread_mutex_lock(&mutex) 函数给资源加上互斥锁,让线程一和线程二访问文件的时候互斥。

原创粉丝点击