Synchronized content in the "UNP2" as the inter-process communication, I think that in fact, synchronization is only a collaborative way of communication between processes a means of collaboration, not known as a form of interprocess communication, so the title with "Synchronization", and not using IPC interprocess communication.
Mutexes are the basic components of synchronization, and they are always used to synchronize individual threads within a process. If a mutex or condition variable resides in a memory area that is shared among multiple processes, POSIX also allows it to be used for synchronization between these processes.
mutexes are used to protect critical sections to ensure that only one thread is executing code at any time, or that only one process executes it at any time. the code form of the Protection critical section is generally as follows:
Lock_the_mutex (); Critical zone Unlock_the_mutex ();
Since at any moment only one thread can lock a given mutex, such code guarantees that only one thread executes the instruction in its critical section at any moment.
POSIX mutexes are declared as variables with the pthread_mutex_t data type. If the mutex variable is statically assigned, it can be initialized to a constant value of pthread_mutex_initializer, for example:
static pthread_mutex_t lock = Pthread_mutex_initializer;
If the mutex is dynamically allocated, or is allocated in a shared memory area, it must be initialized at run time by calling the Pthread_mutex_init function.
#include <pthread.h>int pthread_mutex_lock (pthread_mutex_t *mptr); int Pthread_mutex_trylock (pthread_mutex_t * MPTR); int Pthread_mutex_unlock (pthread_mutex_t *mptr);
If you try to give a mutex lock that has been locked by another thread, the Pthread_mutex_lock will block until the mutex is unlocked. Pthread_mutex_trylock is the corresponding non-blocking function, and if the mutex is locked, it returns a ebusy error. mutexes Protect shared data for multiple threads or critical sections shared by multiple processes.
producer consumer problems are a classic problem in synchronization : one or more producers (threads or processes) Create data entries, which are then processed by one or more consumers (threads or processes). Data entries are passed between producers and consumers using some kind of IPC.
synchronization is divided into explicit and implicit synchronization. the plumbing problem in the shell is a producer consumer problem, such as grep pattern chapters.*|wc-l. This type of synchronization is implicit in that producers and consumers do not know that the kernel is performing synchronization. If Message Queuing is used as the IPC form between producer consumers, the kernel still handles synchronization, that is, synchronization is still implicit. However, when the shared memory area is used as the IPC form between producer and consumer, producers and consumers must perform some kind of explicit synchronization, which is explicit synchronization.
The process of implementing producer consumers in a waiting manner is as follows:
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define Maxnitems 1000000#define maxnthreads 100intnitems;/*read-only by producer and Consumer*/struct{pthread_mutex_tmutex;i Ntbuff[maxnitems];int Nput;intnval;} Shared={pthread_mutex_initializer};void *produce (void*), *consume (void*); int min (int a, int b) {return ((a < b)? a:b); }intmain (int argc, char **argv) {int I, nthreads, count[maxnthreads];p thread_ttid_produce[maxnthreads], tid_consume;if (argc! = 3) {printf ("Usage:produce < #items > < #threads >.\n"); return-1;} Nitems = Min (atoi (argv[1)), maxnitems), nthreads = Min (atoi (argv[2)), maxnthreads);p thread_setconcurrency (nthreads); *start all the producer threads*/for (i = 0; i < nthreads; i++) {Count[i] = 0;pthread_create (&tid_produce[i], NULL, p Roduce, &count[i]);} /*wait for all the producer threads*/for (i = 0; i < nthreads; i++) {Pthread_join (tid_produce[i], NULL);p rintf ("count[%d" =%d\n ", I, Count[i]);} /*starT, then wait for the consumer thread*/pthread_create (&tid_consume, NULL, consume, NULL);p Thread_join (Tid_consume, NULL); exit (0);} void *produce (void *arg) {for (;;) {Pthread_mutex_lock (&shared.mutex); if (Shared.nput >= nitems) {pthread_mutex_unlock (&shared.mutex); return (NULL);/*array if full, we ' re done*/}shared.buff[shared.nput] = shared.nval;shared.nput++;shared.nval++; Pthread_mutex_unlock (&shared.mutex); * ((int *) arg) + = 1;}}The program for which the mutex waits instead of waiting is as follows:
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define Maxnitems 1000000#define maxnthreads 100intnitems;/*read-only by producer and Consumer*/struct{pthread_mutex_tmutex;i Ntbuff[maxnitems];int Nput;intnval;} Shared={pthread_mutex_initializer};void *produce (void*), *consume (void*); int min (int a, int b) {return ((a < b)? a:b); }intmain (int argc, char **argv) {int I, nthreads, count[maxnthreads];p thread_ttid_produce[maxnthreads], tid_consume;if (argc! = 3) {printf ("Usage:produce < #items > < #threads >.\n"); return-1;} Nitems = Min (atoi (argv[1]), maxnitems), nthreads = Min (atoi (argv[2)), maxnthreads);/*create all producers and one consumer */pthread_setconcurrency (nthreads + 1);/*start all the producer threads*/for (i = 0; i < nthreads; i++) {Count[i] = 0;pth Read_create (&tid_produce[i], NULL, produce, &count[i]);} Pthread_create (&tid_consume, NULL, consume, NULL);/*wait for all the producer and the consumer*/for (i = 0; i < nthreads; i++) {pthread_join (tid_produce[i], NULL);p rintf ("count[%d] =%d\n", I, Count[i]);} Pthread_join (Tid_consume, NULL); exit (0);} void *produce (void *arg) {for (;;) {Pthread_mutex_lock (&shared.mutex); if (Shared.nput >= nitems) {pthread_mutex_unlock (&shared.mutex); return (NULL);/*array if full, we ' re done*/}shared.buff[shared.nput] = shared.nval;shared.nput++;shared.nval++; Pthread_mutex_unlock (&shared.mutex); * ((int *) arg) + = 1;}} void consume_wait (int i) {for (;;) {Pthread_mutex_lock (&shared.mutex), if (I < shared.nput) {Pthread_mutex_unlock (&shared.mutex); return;/* An item is Already*/}pthread_mutex_unlock (&shared.mutex);}} void *consume (void *arg) {int i;for (i = 0; i < Nitems; i++) {consume_wait (i); if (shared.buff[i]! = i) {printf ("buff[%d] =% D\n ", I, Shared.buff[i]);}} return NULL;}