1. Well-known semaphores & nameless semaphores
In the POSIX standard, the semaphore is divided into two types, one is the nameless semaphore, and the other is a well-known semaphore. The nameless semaphore is only used for synchronization between threads, and a known semaphore is used only for interprocess communication. The semaphore is belong to the Posix:sem, not belong to the POSIX:THR, need the file head is <semaphore.h>. The common denominator is the equivalent of a counter, which restricts access to limited shared resources by multiple processes
2. Related functions
1) Create a semaphore
int Sem_init (sem_t* sem, int pshared,unsigned int value);
SEM- semaphore ID, output.
pshared- generally take 0 that represents the semaphore of the calling process. A non- 0 means that the semaphore can share memory in a way that is shared by multiple processes (Linux is temporarily not supported ).
Value- initial value of signal volume.
2) Semaphore operation function
int sem_post (sem_t* sem);//signal volume plus 1int sem_wait (sem_t* sem);//signal volume minus 1, not enough to block int sem_trywait (sem_t* sem);//signal volume minus 1, not enough to reduce the return-1, errno is Eagainint sem_timedwait (sem_t* sem, const struct timespec* abs_timeout);//The semaphore is reduced by 1, not enough to block until the Abs_timeout timeout returns-1, errno to Etimedout
struct Timespec { time_t tv_sec; Seconds long tv_nsec;//nanoseconds [0-999999999]};
int Sem_getvalue (sem_t *sem, int *sval),//The current value of the semaphore pointed to by the SEM is placed on the integer that the sval points to
3) destroy the semaphore
int Sem_destroy (sem_t* sem);
3. And the difference between the mutual exclusion and contact:
mutexes allow only one thread to access a shared resource at any time, and semaphores allow up to value threads access shared resources concurrently when value 1
#include <stdio.h> #include <string.h> #include <pthread.h> #include <semaphore.h>unsigned int G_CN = 0;sem_t g_sem;void* thread_proc (void* arg) {unsigned int i;for (i = 0; i < 100000; i++) {sem_wait (&g_sem); G_cn++;sem_post (&g_sem);} return NULL;} int main (void) {size_t i;pthread_t tids[2];int error;sem_init (&g_sem, 0, 1); for (i = 0; i < sizeof (TIDs)/Sizeo F (Tids[0]); i++) if (Error = Pthread_create (&tids[i], NULL, thread_proc,null))! = 0) {fprintf (stderr, "Pthread_create:%s\n", St Rerror (Error)); return-1;} for (i = 0; i < sizeof (tids)/sizeof (Tids[0]) (i++) if (Error = Pthread_join (Tids[i], NULL))! = 0) {fprintf (stderr , "Pthread_join:%s\n", strerror (Error)); return-1;} Sem_destroy (&g_sem);p rintf ("G_CN =%u\n", G_CN); return 0;}
Results no matter how many times it runs, it is 200,000
4. Simulation Internship A connection pooling problem that is used to access limited resources:
#include <stdio.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include < Semaphore.h> #define MAX_CONNS 5//Maximum number of connections # Max_users 50//Maximum number of users sem_t g_sem;void* thread_user (void* Arg) {Pthrea d_t tid = pthread_self (), int sval;sem_getvalue (&g_sem, &sval);p rintf ("%lu thread: Waiting for database connection (%d free connections left) ... \ n", Tid, Sval); sem_wait (&g_sem); Sem_getvalue (&g_sem, &sval);p rintf ("%lu thread: Get a database connection (%d free connections left)!" \ n ", Tid, Sval); Usleep (1000000); Sem_post (&g_sem); Sem_getvalue (&g_sem, &sval);p rintf ("%lu Thread: Release database connection (left %d idle connections). \ n ", Tid, Sval); return NULL;} int main (void) {size_t i;pthread_t tids[max_users];int error;sem_init (&g_sem, 0, Max_conns); Create 50 threads for (i = 0; i < sizeof (tids)/sizeof (tids[0]); i++) if (Error = Pthread_create (&tids[i], NULL, Thread_ User,null))! = 0) {fprintf (stderr, "Pthread_create:%s\n", strerror (Error)); return-1;} Recycle thread for (i = 0; i < sizeof (tids)/sizeof (tids[0]); i++) if (Error =Pthread_join (Tids[i], NULL))! = 0) {fprintf (stderr, "Pthread_join:%s\n", strerror (Error)); return-1;} Destroy the semaphore Sem_destroy (&G_SEM); return 0;}
Some result graphs:
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Thread Sync---semaphore (nameless)