pthread_cond_t 的应用

名称
   pthread_cond_init, pthread_cond_destroy, pthread_cond_signal,
   pthread_cond_broadcast, pthread_cond_wait, pthread_cond_timedwait - 状态操作。
  
  大纲
   #include 
   pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
   int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
  int pthread_cond_signal(pthread_cond_t *cond);
   int pthread_cond_broadcast(pthread_cond_t *cond);
   int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
  int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct 
  timespec *abstime);
  int pthread_cond_destroy(pthread_cond_t *cond);
  
  描述
  状态变量是一种同步设备,它允许线程挂起并放弃CPU时间以等待某些共享变量满足状态。操作状态变量的基本操作:当状态满足时发送信号,等待状态满足,在其它线程发送状态信号之前挂起线程。
  状态变量通常和互斥体联系在一起,为了避免竞争状态出现,一个线程准备等待一个状态变量之前另外一个线程要先设置好状态信号。
  
   pthread_cond_init初始化状态变量cond,使用cond_attr中定义了的状态属性,如果cond_attr为NULL,将会使用默认属性。LinuxThreads的实现支持没有任何属性的cond_attr,因此,cond_attr就是被忽略的。
   pthread_cond_t类型的变量也可以使用PTHREAD_COND_INITIALIZER.常量进行静态的初始化。
  
   pthread_cond_signal函数重新开始一个正在等待cond变量的线程。如果没有线程在等待cond变量,不执行任何操作。如果有多个线程都在等待,某个匹配的线程会被重新开始,但是不一定是哪个。
  
   pthread_cond_broadcast函数重新开始所有在等待cond变量的线程。如果没有线程在等待cond变量,不执行任何操作。
  
   pthread_cond_wait函数对互斥体进行原子的解锁工作(就像pthread_unlock_mutex),然后等待状态信号。线程被挂起并不消耗CPU时间,直到发送状态信号。互斥体必须被调用者锁定。在返回调用线程之前,互斥锁被pthread_cond_wait拥有。
  
  释放互斥体和在状态变量上挂起是自动进行的。因此,如果所有的线程经常在状态信号之前要求互斥体,这会保证在线程在状态变量上锁定互斥体的期间状态变量不会触发信号。
  
   pthread_cond_timedwait函数自动释放互斥体并且等待cond状态,就像pthread_cond_wait所做的一样,但是它限制了最大的等待时间。如果cond没有在一定时间内用abstime中没有指定的时间做标记,互斥体会重新获得,然后返回错误码ETIMEOUT。abstime参数指定绝对时间,和time(2)和gettimeofday(2)的一样:以格林威治时间1970年1月1日零点为起点。
  
   pthread_cond_destroy函数销毁状态变量,释放它可能持有的资源。没有线程必须在这里等待状态变量。在LinuxThreads实现中,状态变量不与任何资源有关系,所以这个接口除了检查状态变量上是否有等待的线程之外不做任何事。
  
  取消
   pthread_cond_wait和pthread_cond_timedwait都是取消点。如果某个线程在某个这样的函数中挂起后又被取消,该线程会重新开始执行,然后再锁定互斥体。(尚未完成!)
  
  同步信号安全
  状态函数不是同步安全的,不应该出现在信号处理函数中。特别的,从信号处理函数中调用pthread_cond_signal或pthread_cond_broadcast会导致死锁。
  
  返回值
  所有状态变量函数在成功的时候返回0,在出错的时候返回出错码。
  
  错误码
   pthread_cond_init, pthread_cond_signal, pthread_cond_broadcast和pthread_cond_wait从来都不会返回出错码。
  
   pthread_cond_timedwait函数在出错时返回下面的出错码:
   ETIMEOUT:状态变量在abstime限定时间内没有激发信号。
   EINTR:pthread_cond_timedwait被信号中断。
  
  pthread_cond_destroy函数在出错时返回下面的出错码:
   EBUSY:有线程正在cond上等待。
  
  作者
   Xavier Leroy 
  
  参见
   pthread_condattr_init(3), pthread_mutex_lock(3), pthread_mutex_unlock(3)
   gettimeofday(2), nanosleep(2).
  
  示例
  考虑两个共享变量x和y,使用互斥体mut进行保护,一个状态变量cond在x大于y时激发信号。
   int x,y;
  pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
  pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  
  一直等待,直到x大于y:
  
  pthread_mutex_lock(&mut);
  while (x <= y) {
  pthread_cond_wait(&cond, &mut);
  }
  /* operate on x and y */
  pthread_mutex_unlock(&mut);
  
  修改x和y可能会使x大于y。如果需要就应该发送信号:
  
  pthread_mutex_lock(&mut);
  /* modify x and y */
  if (x > y) pthread_cond_broadcast(&cond);
  pthread_mutex_unlock(&mut);
  
  如果可以证明,至多有一个等待中的线程需要醒来(例如,只有两个线程,通过x和y联系起来),pthread_cond_signal可以作为可选的更有效率的轻量级的pthread_cond_broadcast.。如果不能确定,使用pthread_cond_broadcast函数。
  
  要在5秒钟内等待x大于y,像下面:
   struct timeval now;
   struct timespec timeout;
   int retcode;
  
   pthread_mutex_lock(&mut);
   gettimeofday(&now);
   timeout.tv_sec = now.tv_sec + 5;
   timeout.tv_nsec = now.tv_usec * 1000;
   retcode = 0;
  
   while (x <= y && retcode != ETIMEDOUT) {
   retcode = pthread_cond_timedwait(&cond, &mut, &timeout);
   }
  
   if (retcode == ETIMEDOUT) {
   /* timeout occurred */
   } else {
   /* operate on x and y */
   }
  
   pthread_mutex_unlock(&mut);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
pthread_cond_wait() 可以用于线程之间的同步,当一个线程需要等待另一个线程完成某个操作后再继续执行时,可以使用 pthread_cond_wait()。下面是一个简单的示例: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int count = 0; void *producer(void *arg) { for (int i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); // 加锁 count++; printf("Producer: produced item %d\n", count); pthread_cond_signal(&cond); // 发送信号 pthread_mutex_unlock(&mutex); // 解锁 } pthread_exit(NULL); } void *consumer(void *arg) { for (int i = 0; i < 10; i++) { pthread_mutex_lock(&mutex); // 加锁 while (count == 0) { // 如果 count 为 0,等待信号 pthread_cond_wait(&cond, &mutex); } printf("Consumer: consumed item %d\n", count); count--; pthread_mutex_unlock(&mutex); // 解锁 } pthread_exit(NULL); } int main() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, producer, NULL); pthread_create(&tid2, NULL, consumer, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); return 0; } ``` 在这个示例中,生产者线程和消费者线程共享一个变量 count,生产者线程不断地增加 count,消费者线程不断地减少 count,但是当 count 为 0 时,消费者线程必须等待生产者线程生产出新的物品。为了实现这个功能,我们使用了 pthread_cond_wait()。在消费者线程中,如果 count 为 0,就调用 pthread_cond_wait() 等待生产者线程发送信号。当生产者线程生产出新的物品时,调用 pthread_cond_signal() 发送信号,消费者线程就可以继续执行了。注意,在使用 pthread_cond_wait() 时,必须先加锁,等待信号时自动解锁,信号到来时自动加锁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值