void* Thread1(void){
  while(线程运行条件成立){
    …
    pthread_mutex_lock(qlock);
    while(条件成立)
pthread_cond_wait(qcond,qlock);
或者
pthread_cond_wait(qcond,qlock,timeout);
      reset条件变量…
    pthread_mutex_unlock(qlock);
  }
}

void* Thread2(void){
  while(线程运行条件成立){
    …
    pthread_mutex_lock(qlock);
    set了条件变量…//可以发送处理信号
    pthread_cond_signal(qcond);
    或者
    pthread_cond_broadcast(qcond);
    pthread_mutex_unlock(qlock);
  }
}

  原型:int
pthread_mutex_init(pthread_mutex_t *restrict mutex, const
pthread_mutexattr_t *restric attr);

条件变量需要配合互斥量一起使用,互斥量作为参数传入wait函数,函数把调用线程放到等待条件的线程列表上,然后对互斥量解锁,这两个是原子操作。当线程等待到条件,从wait函数返回之前,会再次锁住互斥量。

  说明: 如果使用默认的属性初始化互斥量,只需把attr设为NULL

您可能感兴趣的文章:

初始化:  在Linux下,
线程的互斥量数据类型是pthread_mutex_t. 在使用前,
要对它进行初始化:对于静态分配的互斥量,
可以把它设置为PTHREAD_MUTEX_INITIALIZER,
或者调用pthread_mutex_init.对于动态分配的互斥量,
在申请内存(malloc)之后, 通过pthread_mutex_init进行初始化,
并且在释放内存(free)前需要调用pthread_mutex_destroy.

第2,3,4步是wait的内部操作

  int
pthread_mutex_lock(pthread_mutex_t *mutex); 

Linux线程同步之间存在多种机制,条件变量是一种类似操作系统里提到的生产者-消费者算法的同步机制,允许线程以无竞争的方式等待特定条件的发生。

互斥操作: 对共享资源的访问,
要对互斥量进行加锁, 如果互斥量已经上了锁, 调用线程会阻塞,
直到互斥量被解锁. 在完成了对共享资源的访问后, 要对互斥量进行解锁   

在wait被唤醒后,还需要在while中去检查条件,这是为了防止“惊群效应”,比如有两个线程同时阻塞在wait,先后醒来,快的线程做完处理然后把条件reset了,并且对互斥量解锁,此时慢的线程在wait里获得了锁(即第4步)返回,还再去做处理就会出问题。

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

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 
int lock_var; 
time_t end_time; 

void pthread1(void *arg); 
void pthread2(void *arg); 

int main(int argc, char *argv[]) 
{ 
      pthread_t id1,id2; 
      pthread_t mon_th_id; 
      int ret; 

      end_time = time(NULL)+10; 
            /*互斥锁初始化*/ 
      pthread_mutex_init(&mutex,NULL); 
            /*创建两个线程*/ 
      ret=pthread_create(&id1,NULL,(void *)pthread1, NULL); 
      if(ret!=0) 
              perror("pthread cread1"); 
      ret=pthread_create(&id2,NULL,(void *)pthread2, NULL); 
      if(ret!=0) 
              perror("pthread cread2");
      pthread_join(id1,NULL); 
      pthread_join(id2,NULL); 
      exit(0); 
} 

void pthread1(void *arg) 
{ 
      int i; 
      while(time(NULL) < end_time){ 
                    /*互斥锁上锁*/ 
          if(pthread_mutex_lock(&mutex)!=0){ 
              perror("pthread_mutex_lock"); 
          } 
          else 
            printf("pthread1:pthread1 lock the variable\n"); 
          for(i=0;i<2;i++){ 
            sleep(1); 
            lock_var++; 
          } 
                    /*互斥锁接锁*/ 
          if(pthread_mutex_unlock(&mutex)!=0){ 
            perror("pthread_mutex_unlock"); 
          } 
          else 
            printf("pthread1:pthread1 unlock the variable\n"); 
              sleep(1); 
      } 
} 

void pthread2(void *arg) 
{ 
      int nolock=0; 
      int ret; 
      while(time(NULL) < end_time){ 
                    /*测试互斥锁*/ 
          ret=pthread_mutex_trylock(&mutex); 
          if(ret==EBUSY) 
                 printf("pthread2:the variable is locked by pthread1\n"); 
          else{ 
                 if(ret!=0){ 
                     perror("pthread_mutex_trylock"); 
                     exit(1); 
                 } 
                 else 
                     printf("pthread2:pthread2  got  lock.The  variable  is %d\n",lock_var); 
                                 /*互斥锁接锁*/ 
                 if(pthread_mutex_unlock(&mutex)!=0){ 
                     perror("pthread_mutex_unlock"); 
                 } 
                 else 
                     printf("pthread2:pthread2 unlock the variable\n"); 
          } 
          sleep(3); 
      } 
}

zhaoxj$ ./thread_mutex
pthread1:pthread1 lock the variable
pthread2:the variable is locked by pthread1
pthread1:pthread1 unlock the variable
pthread2:pthread2  got  lock.The variable is 2
pthread2:pthread2 unlock the variable
pthread1:pthread1 lock the variable
pthread1:pthread1 unlock the variable
pthread2:pthread2  got  lock.The variable is 4
pthread2:pthread2 unlock the variable
pthread1:pthread1 lock the variable
pthread1:pthread1 unlock the variable
pthread2:pthread2  got  lock.The variable is 6
pthread2:pthread2 unlock the variable
pthread1:pthread1 lock the variable
pthread1:pthread1 unlock the variable

(实现一段代码原子操作)说明:mutex互斥信号量锁住的不是一个变量,而是阻塞住一段程序。如果对一个mutex变量执行了第一次pthread_mutex_lock(mutex)之后,在unlock(mutex)之前的这段时间内,如果有其他线程也执行到了pthread_mutex_lock(mutex),这个线程就会阻塞住,直到之前的线程unlock之后才能执行,由此,实现同步,也就达到保护临界区资源的目的

1.Lock
2.Unlock
3.等待
4.Lock
5.Unlock

  #include <pthread.h>

示例伪代码:

等待条件有两种方式:无条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间1970年1月1日0时0分0秒。 

以上就是小编为大家带来的浅谈Linux条件变量的使用全部内容了,希望大家多多支持脚本之家~

无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race
Condition)。在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在线程挂起进入等待时mutex将被解锁;在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。可概括为:调用pthread_cond_wait()前线程要显示的加锁,pthread_cond_wait()结束后线程要显示的解锁。pthread_cond_wait()被调用时对本线程的互斥量进行行隐式解锁和加锁过程。

问题解释:当程序进入pthread_cond_wait等待后,将会把g_mutex进行解锁,当离开pthread_cond_wait之前,g_mutex会重新加锁。所以在main中的g_mutex会被加锁。

测试实例进一步了解互斥

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

创建和注销                                                            
                             

1)条件变量和互斥锁一样,都有静态动态两种创建方式,静态方式使用PTHREAD_COND_INITIALIZER常量:pthread_cond_t
cond=PTHREAD_COND_INITIALIZER;动态方式调用pthread_cond_init()函数:int
pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t
*cond_attr)

互斥锁机制(Mutual
exclusion,缩写为Mutex)是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制。该目的通过将代码切片成一个一个的临界区域(critical
section)达成。临界区域指的是一块对公共资源进行存取的代码,并非一种机制或是算法

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图