Linux learning - a condition variable synchronization

       With different mutex, condition variables are used instead of waiting for locked. Condition variables used to automatically block a thread until certain special circumstances. Normal condition variables and mutex simultaneously.
       Condition variables so that we can sleep waiting for some conditions occur. Condition variable is the use of global variables shared between threads a mechanism for synchronizing, comprising two major actions: a thread to wait "condition is satisfied condition variable" hang; another thread so that the "condition is established" (given condition is satisfied signal).
       Detecting conditions is carried out under the protection mutex. If a condition is false, a thread is blocked automatically, and release the mutex wait state changes. If another thread has changed conditions, it signals to the associated condition variable, or a plurality of wake-up threads waiting for it to regain mutex, re-evaluation of the condition. If the two processes share the read-write memory, condition variables can be used to implement thread synchronization between these two processes.
       It must first be initialized before using condition variables. And may generate a condition variable initialization as a single statement: pthread_cond_t my_condition = PTHREAD_COND_INITIALIZER; (thread for inter-process communication). Pthread_cond_init dynamic initialization function may be utilized.
       Condition variables is divided into two parts: the conditions and variables condition itself is protected by a mutex lock mutex thread must first before changing the condition of the state which uses global variables shared among threads were a mechanism to synchronize...

Related functions as follows:

1 int pthread_cond_init(pthread_cond_t *cond,pthread_condattr_t *cond_attr);     
2 int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
3 int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);
4 int pthread_cond_destroy(pthread_cond_t *cond);  
5 int pthread_cond_signal(pthread_cond_t *cond);
6 int pthread_cond_broadcast(pthread_cond_t *cond);  //解除所有线程的阻塞

Brief Description of:
(1) Initialization .init () or pthread_cond_t cond = PTHREAD_COND_INITIALIER; attribute is set to NULL
(2) wait condition is satisfied .pthread_wait, pthread_timewait.wait () releases the lock, and blocking wait condition variable is true
TIMEWAIT () Set Wait time, yet signal, return ETIMEOUT (lock ensures that only one thread the wait)
(3) activation condition variables: pthread_cond_signal, pthread_cond_broadcast (activate all waiting threads)
(4) Clear condition variables: destroy; wireless waiting process, otherwise EBUSY

Detailed Description
1. Initialization:

Data type pthread_cond_t condition variable is used, it must be initialized before use, which includes two ways:

Static: You can put constant PTHREAD_COND_INITIALIZER to statically allocated condition variable.

Dynamic: pthread_cond_init function, before the release of the memory space is a dynamic condition variable, use pthread_cond_destroy be cleaned.

#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, 出错则返回错误编号.

When pthread_cond_init attr parameter is NULL, it will create a default condition variable attributes; discussion after non-default.

2. Wait conditions:

#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, 出错则返回错误编号.

These two functions are blocked waiting and waiting for a timeout. Con wait wait condition becomes true, is passed to the mutex pthread_cond_wait the conditions for protection, the caller passes mutex locked to the function. Function to the calling thread placed on the list of threads waiting condition, then the mutex is unlocked, these two operations are atomic. such closed condition check and will thread into the sleep state waits for the channel condition changed between the time of these two operations, so that the thread any change in conditions will not miss.

When pthread_cond_wait return, the mutex is locked again.

3. Notification conditions:

#include <pthread.h>

int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);

成功则返回0, 出错则返回错误编号.

These two functions are used to inform the threads have been met. These functions are called, also known as sending a signal to the thread or conditions. It must be noted, must give thread signals changing conditions in the future state.

Condition variable synchronization instance - the sale of control of instant noodles

// pthread_cond_t cond;  定义一个条件变量
   14 // pthread_cond_init;   初始化条件变量
   15 // pthread_cond_destroy  销毁
   16 // pthread_cond_wait    等待
   17 // pthread_cond_signal  通知  等待在条件变量 上的线程
   18 
   19 
   20 
   21 
   22 #include<stdio.h>
   23 #include<unistd.h>
   24 #include<pthread.h>
   25 #include<stdlib.h>
   26 
   27 int g_judge=0;               //0代表没有方便面  1代表有方便面
   28 pthread_mutex_t mutex;
   29 pthread_cond_t full;
   30 pthread_cond_t empty;
   31 
   32 
W> 33 void* sale_noodles(void* arg)
   34 {
   35   
   36  while(1)
   37  {
   38     // usleep(300);
   39     
   40    pthread_mutex_lock(&mutex);                                                                                                                              
   41 
   42    while(g_judge==1)
    //先解锁
   47      //集合了 解锁+ 休眠+ 被唤醒后加锁  的原子操作
   48      pthread_cond_wait(&full,&mutex);                        //这个 mutex 有什么用?    --->   ++g_judge不是一个原子操作,涉及到对临界资源的修改,多对多情况>      下不安全  
   49 
   50 
   51    }
   52      printf("product one noodle\n");
   53      g_judge++;
   54      //因为买方便面一直在wait死等,所以还需要通知一下
   55      pthread_cond_signal(&empty);
E> 56      pthread_mutex_unlock(mutex);
   57  
   58  }
   59 
   60 
   61      return NULL;
   62 
   63 }
   64 
   65 
   66 
E> 67 
   68 
   69 
   70 
E> 71 void* buy_noodles(void* arg)
   72 {                                                                                                                                                           
   73  
   74 
   75                                                           
   76 
   77 while(1)
{
pthread_mutex_lock(&mutex);                //这块为什么加锁,涉及到对临界资源的访问
   80   
   81   //如果没有方便面,就要等待
   82   while(g_judge==0)                     //必须得用 while 判断  因为有很多线程不停的判断
   83    {
   84       //int pthread_cond_wait( ...  )
   85     pthread_cond_wait(&empty,&mutex);                //解锁 和 挂起等待 必须是一个原子操作 ,否则不安全    &&  完成之后如果被唤醒会重新尝试加锁
   86   
   87    
   88    
   89    }
   90 
   91   
   92   printf("eat one noodle~~~\n");
   93   g_judge--;
   94   pthread_cond_signal(&full); 
   95   pthread_mutex_unlock(&mutex);
   96   
   97 }
   98 
   99 
  100   return NULL;
  101 
  102 }
  103 
         int main()
  115 {
  116  
  117   pthread_cond_init(&full,NULL); 
  118   pthread_cond_init(&empty,NULL); 
  119   pthread_mutex_init(&mutex,NULL);
  120   
  121   pthread_t tid1,tid2;
  122   pthread_create(&tid1,NULL,sale_noodles,NULL);
E>123   pthread_create(&tid2,NULL,buy_noodles,NULL);
  124 
  125   pthread_join(tid1,NULL);
  126   pthread_join(tid2,NULL);
  127 
  128   pthread_mutex_destroy(&mutex);
  129   pthread_cond_destroy(&full);
  130   pthread_cond_destroy(&empty);
  131 
  132 }

Note: We have to create two condition variables empty and full. Buyers and sellers wait time are waiting on their condition variable. If both buyers and sellers at the same time on the same conditions and other variables, then, BUG will be prone in the case of multi-threaded; Another point is that there are parameters pthread_cond_wait Why mutex, because it is a collection of unlocked + Sleep + after wakeup plus lock atomic operation.

//集合了 解锁+ 休眠+ 被唤醒后加锁  的原子操作
    pthread_cond_wait(&full,&mutex);   

Guess you like

Origin blog.csdn.net/tonglin12138/article/details/93013197