The thread semaphore is similar to the process semaphore, and UNIX provides two sets of semaphore-related APIs. POSIX and System v. Both sets of APIs can be used in threads and processes.
The use of semaphores in the process is to ensure the control of critical resources, the thread has a mutex, and there are conditional variables to control the thread, the semaphore is not a bit redundant?
In fact, in the process can also use mutexes and control variables, semaphores and the lock is similar, but in fact there is an essential difference.
Thread Lock: Only 01 operations are allowed on critical resources, and the CPU only allows one thread to occupy at a time. Who locks who unlocks.
Semaphore: PV operation, to increase or decrease the counter in the structure, allow multiple threads to enter the critical resources, there is no limit must the same thread to occupy and release the semaphore.
For example, AB two threads are accessing critical resources, C threads are blocking, as long as AB is arbitrarily released, C can get the semaphore.
The following is the code for the thread used by the Semop class that communicates with the previous process.
1#include <pthread.h>2#include <unistd.h>3#include <sys/sem.h>4#include <iostream>5 6 using namespacestd;7 8 classThreadinterface9 {Ten Public: One voidCreateThread (void* (*func) (void*),void*sem); A voidWaitthread (); - Private: - pthread_t M_ptread; the }; - - voidThreadinterface::createthread (void* (*func) (void*),void*sem) - { +Pthread_create (&M_ptread, NULL, func, SEM); - } + A voidThreadinterface::waitthread () at { - Pthread_join (M_ptread, NULL); - } - - classSemOp - { in Public: -SemOp (): M_isemid (0){}; to voidInitsem (); + voidGetsem (); - voidReleasesem (); the voidDelsem (); * Private: $ intM_isemid;Panax Notoginseng }; - the voidSemop::initsem () + { A if(M_isemid = Semget (Ipc_private,1,0600| ipc_creat)) <=0) thecout<<"Get Semid failure!"<<Endl; +Semctl (M_isemid,0, Setval,1); - } $ $ voidSemop::getsem () - { - structsembuf Sem_get; theSem_get.sem_num =0; -Sem_get.sem_op =-1;WuyiSEM_GET.SEM_FLG =Sem_undo; theSemop (M_isemid,&sem_get,1); - } Wu - voidSemop::releasesem () About { $ structsembuf sem_release; -Sem_release.sem_num =0; -Sem_release.sem_op =1; -SEM_RELEASE.SEM_FLG =Sem_undo; ASemop (M_isemid,&sem_release,1); + } the - voidSemOp::D elsem () $ { theSemctl (M_isemid,0, ipc_rmid); the } the the classService - { in Public: the Static void* Run (void*Psem) the { AboutSemOp *sem = reinterpret_cast<semop*> (Psem);//Strong pointer Turn theSem->Getsem (); the for(inti =0; I <5; ++i) the { +cout<<"This is thread 2!"<<Endl; -Sleep1); the }BayiSem->Releasesem (); the } the }; - - intMain () the { the Service Srv; the threadinterface Thread; the SemOp sem; - the SEM. Initsem (); theThread.createthread (&srv.run, &sem);//incoming semaphore to thread the 94 SEM. Getsem (); the for(inti =0; I <5; ++i) the { thecout<<"This is thread 1!"<<Endl;98Sleep1); About } - SEM. Releasesem ();101 Thread.waitthread ();102 SEM. Delsem ();103 return 0;104}
Test results:
The result is the same as the mutex effect, or it can be used with the condition variable!
Thread Synchronization (three)--semaphore