Signal Volume
The semaphore is an upgraded version of the mutex that turns 1 in the mutex into N, for a simple example: suppose there are 10 people now, a cell phone, and 10 people are competing to use the phone to call this is the mutex. For the semaphore, there may now be 4 phones, 10 of whom are competing to make phone calls. The amount of the mutex signal is changed from 1 to 4. Signal volume is the operating system of PV operation, it is widely used in the process or between threads synchronization and mutual exclusion.
Introduction to related library functions
#include <semaphore.h>//Required header file//initialization semaphore when the SEM is initialized, you can specify the initial value of the semaphore, and whether the value can be shared between multiple processes to indicate the initial value of the semaphore, pshared indicates whether the process is shared before any more processes. 0 means not sharing between multiple processes, not 0 means sharing between multiple processes specific can man sem_init//successfully return 0, error returned -1int sem_init (sem_t *sem, int pshared, unsigned int value); int sem_wait (sem_t *sem)//equivalent to P operation Int sem_try_wait (sem_t *sem)//equivalent to P operation, in the semaphore value greater than 0 o'clock can be the value of the semaphore minus one, and the difference between the above sem_wait is, The signal value is less than 0 o'clock int sem_post (sem_t *sem)//equivalent to v operation Int Sem_getvalue (sem_t *sem)//for getting semaphore value int sem_destory (sem_t *sem)//release semaphore
Semaphore Example: Producer consumption value
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define BUFSIZE 10int buf[bufsize];sem_t consumer_sem,producer_sem;void *consumer (void *arg) {int C=0;while (1) {sem_wait ( &CONSUMER_SEM);//start consuming Consumer_sem value minus one printf ("Consumer%d:%d\n", c,buf[c]);//consumption data c++;c=c%bufsize; Sleep (1);//Sleeping 1ssem_post (&producer_sem),//producer_sem value plus 1}}void *producer (void *arg) {int P=0;while (1) {sem_wait (&producer_sem);//start production Producer_sem value minus one buf[p]=rand ()% 1000 + 1;//production data printf ("Producer%d:%d\n", p,buf[p]);p + +;p =p %bufsize;sem_post (&consumer_sem);//consumer_sem value plus 1}}int main () {sem_init (&consumer_sem,0,0); Sem_init ( &producer_sem,0,bufsize);p thread_t pid,cid;pthread_create (&pid,null,producer,null);p thread_create (& Cid,null,consumer,null);p thread_join (PID, NULL);p thread_join (CID, NULL); Sem_destroy (&consumer_sem); sem_ Destroy (&producer_sem); return 0;}
Condition variable
A conditional variable is a mechanism for synchronizing a global variable shared between threads, which consists of two actions: one thread waits for the condition variable to be set up, and the other thread causes the condition to be set. To prevent competition, the use of condition variables is always combined with a mutex.
The condition variable type is pthread_cond_t.
Introduction to related library functions
#include <pthread.h>int Pthread_cond_destroy (pthread_cond_t *cond);//resource release for condition variable int pthread_cond_init (pthread_ cond_t *cond,const pthread_condattr_t *attr);//initialization of conditional variables
#include <pthread.h>int pthread_cond_timedwait (pthread_cond_t *restrict cond,pthread_mutex_t *mutex,const struct timespec *abstime); int pthread_cond_wait (pthread_cond_t *cond,pthread_mutex_t *mutex);//wait for a condition to be established. For the timewait () function, you can set a length of time in addition to waiting. int pthread_cond_signal (pthread_cond_t *cond);//a situation where only one thread receives a post-execution action. The active thread only needs to wake the first sleeping thread. Suppose you add only one job job to a queue. Then it's impolite to wake up one worker thread (and then wake up other threads!). ) int Pthread_cond_broadcast (pthread_cond_t *cond);//Broadcast to the child thread message, sub-thread competition execution.
Either way of waiting must be combined with a mutex to prevent multiple threads from simultaneously requesting a race condition for pthread_cond_wait () (or pthread_cond_timedwait ()), and calling Pthread_cond_wait () Before the update condition waits for the queue, the mutex remains locked and unlocked before the thread hangs into the wait before it must be Cheng (Pthread_mutex_lock ()) by this line. Before the condition satisfies thereby leaving pthread_cond_wait (), the mutex will be re-locked to correspond to the lock action before entering Pthread_cond_wait ().
#include <stdlib.h> #include <pthread.h> #include <stdio.h> #include <unistd.h>struct msg { struct MSG *next; int num;}; struct MSG *head;/* condition variable */pthread_cond_t has_product = pthread_cond_initializer;pthread_mutex_t lock = PTHREAD_MUTEX_ Initializer;void *consumer (void *p) {struct MSG *mp; while (1) {pthread_mutex_lock (&lock); /* Pthread_cond_wait (&has_product, &lock); * 1. Blocking waits for has_product to be awakened, * 2. Release the mutex, Pthread_mutex_unlock (&lock) * 3. When awakened, unblock, and reapply for a mutex lock Pthread_mut Ex_lock (&lock) */while (head = = NULL) pthread_cond_wait (&has_product, &lock);//wait 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; while (1) {MP = (struct msg *) 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) wakes up all threads on the waiting queue *///send a signal, telling the consumer that there is a 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;}
Copyright NOTICE: Welcome to reprint, if there are deficiencies, please treatise.
Linux thread Synchronization (ii)