首页 > 代码库 > 3线程同步:条件变量
3线程同步:条件变量
1条件变量
条件变量给多个线程提供了一个汇合的场所。
依赖的头文件
#include<pthread.h>
函数声明
定义分配条件变量
pthread_cond_t cond =PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t*restrict cond, const pthread_condattr_t *restrict attr);
名称: | pthread_cond_init |
功能: | initialize condition variables |
头文件: | #include <pthread.h> |
函数原形: | int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); |
参数: |
|
返回值: | the pthread_cond_destroy() and pthread_cond_init() functions shall return zero; otherwise, an error number shall be returned to indicate the error |
int pthread_cond_destroy(pthread_cond_t*cond);
名称: | pthread_cond_destroy |
功能: | Destroy condition variables |
头文件: | #include <pthread.h> |
函数原形: | int pthread_cond_destroy(pthread_cond_t *cond); |
参数: |
|
函数说明: | 在释放或废弃条件变量之前,需要毁坏它,使用此函数 |
返回值: | the pthread_cond_destroy() and pthread_cond_init() functions shall return zero; otherwise, an error number shall be returned to indicate the error |
int pthread_cond_wait(pthread_cond_t*restrict cond,pthread_mutex_t *restrict mutex);
名称: | pthread_cond_wait |
功能: | Wait on a condition,等待某个条件是否成立。对于timewait()函数除了等待以外,可以设置一个时长。 |
头文件: | #include <pthread.h> |
函数原形: | intpthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex); |
参数: |
|
函数说明: | 一旦初始化了互斥对象和条件变量,就可以等待这个条件,一个特定条件只能有一个互斥对象,而且条件变量应该表示互斥数据“内部”的一种特殊的条件更改。一个互斥条件可以用许多条件变量(例如:cond_empty,cond_full,cond_cleanup),但每个条件变量只能有一个互斥对象。 |
返回值: |
|
int pthread_cond_signal(pthread_cond_t*cond);
名称: | pthread_cond_signal |
功能: | signal a condition,这种情况是只有一个线程收到后执行动作。 |
头文件: | #include <pthread.h> |
函数原形: | int pthread_cond_signal(pthread_cond_t *cond); |
参数: |
|
函数说明: | 活动线程只需要唤醒第一个正在睡眠的线程。假设您只对队列添加了一个工作作业。那么只需要唤醒一个工作程序线程(再唤醒其它线程是不礼貌的!) |
返回值: |
|
int pthread_cond_broadcast(pthread_cond_t*cond);
名称: | pthread_cond_broadcast |
功能: | broadcast a condition,通过广播的形式发给子线程消息,子线程竞争执行。 |
头文件: | #include <pthread.h> |
函数原形: | int pthread_cond_broadcast(pthread_cond_t *cond); |
参数: |
|
函数说明: | 如果线程更改某些共享数据,而且它想要唤醒所有正在等待的线程,则应使用 pthread_cond_broadcast调用 |
返回值: |
|
案例说明:
#include <stdlib.h> #include <pthread.h> #include <stdio.h> #include <unistd.h>
struct msg { struct msg *next; int num; };
struct msg *head; /*条件变量 */ pthread_cond_t has_product = PTHREAD_COND_INITIALIZER; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; void *consumer(void *p) { struct msg *mp; for (;;) { pthread_mutex_lock(&lock); /* pthread_cond_wait(&has_product, &lock); * 1.阻塞等待has_product被唤醒, * 2.释放互斥锁, pthread_mutex_unlock(&lock) * 3.当被唤醒时,解除阻塞,并且重新去申请获得互斥锁 pthread_mutex_lock(&lock) */ while (head == NULL) pthread_cond_wait(&has_product, &lock);
mp = head; head = mp->next; pthread_mutex_unlock(&lock); printf("Consume %d\n", mp->num); free(mp); sleep(rand() % 5); } }
void *producer(void *p) { struct msg *mp; for (;;) { mp = malloc(sizeof(struct msg)); mp->num = rand() % 1000 + 1; printf("Produce %d\n", mp->num); pthread_mutex_lock(&lock); mp->next = head; head = mp; pthread_mutex_unlock(&lock); /* pthread_cond_broadcast(&has_product) 唤醒等待队列上的所有线程*/ //发送信号,告诉消费者有产品了 pthread_cond_signal(&has_product); sleep(rand() % 5); } }
int main(int argc, char *argv[]) { pthread_t pid, cid; srand(time(NULL)); pthread_create(&pid, NULL, producer, NULL); pthread_create(&cid, NULL, consumer, NULL); pthread_join(pid, NULL); pthread_join(cid, NULL); return 0; } |
运行结果:
总结:从上面可以看出,消费者总是消费最先生产出来的一个。
3线程同步:条件变量