Semaphore (Semaphore): sometimes referred to as a semaphore, is a facility used in a multithreaded environment and can be used to ensure that two or more critical sections of code are not called concurrently. The thread must acquire a semaphore before entering a critical code segment, and the thread must release the semaphore once the critical snippet is complete. Other threads that want to enter the critical snippet must wait until the first thread releases the semaphore.
For example, take the operation of a car park as an example. For simplicity, suppose that there are only three parking spaces in the car park and three spaces are empty at the beginning. At the same time, if five vehicles were to come, the janitor would allow three of them to enter directly, then put down the car block, the rest of the car must wait at the entrance, and then the car will have to wait at the entrance. At this time, there is a car left the parking lot, the janitor learned, open the car block, put into the outside of a car, if left two, then can put two, so reciprocating.
In this parking system, parking spaces are public resources, and each car is like a thread, and the gatekeeper acts as the semaphore.
Classification:
Integer semaphore (integer semaphore): Semaphore is a whole number
Recorded Semaphore (record semaphore): Each semaphore s In addition to an integer value S.value (count), there is a process waiting for the queue S.L, which is the identity of each process blocking the semaphore
Binary semaphore (binary semaphore): only 0 or 1 values are allowed for semaphores
Principle:
Semaphore (Semaphore) The kernel object synchronizes the thread, which allows multiple threads to access the same resource at the same time, but needs to limit the maximum number of threads that access this resource at the same time.
When you create a semaphore with CreateSemaphore (), you indicate both the maximum allowable resource count and the current available resource count. In general, the current available resource count is set to the maximum resource count, and each additional thread accesses the shared resource, the current available resource count is reduced by 1, and the semaphore signal can be emitted as long as the current available resource count is greater than 0. However, the current available count is reduced to 0 o'clock indicating that the number of threads currently occupying the resource has reached the maximum allowable number, and the semaphore signal will not be able to be emitted when other threads are allowed to enter. After the thread has finished processing the shared resource, the current available resource count should be added by 1 at the same time as the ReleaseSemaphore () function is left. At any time the currently available resource count is never greater than the maximum resource count.
Note the point:
1. The semaphore belongs to the kernel object, as is the mutex. Running is slow.
2.Semaphore can be abstracted as five operations:
-Create CreateSemaphore (NULL, 1, 5, NULL);
-Wait for WaitForSingleObject (G_HSP, INFINITE); The thread waits for the semaphore, and if the value is greater than 0, the value is reduced by one, and if it is only 0, a straight line goes to sleep, knowing that the semaphore value is greater than 0 or times out.
-Release ReleaseSemaphore (G_HSP, 1, NULL); Executes the release semaphore, the value is added one, and if there is a waiting thread at this time, the thread is awakened.
-Destruction of CloseHandle (G_HSP);
3.
Function Prototypes:
CreateSemaphore
(
Lpsecurity_attributes lpsemaphoreattributes,//Safety Control
LONG linitialcount,//Initial Resource quantity (number of each start)
LONG lmaximumcount,//Maximum number of concurrent (up to start)
LPCWSTR Name of lpname//number
);
lMaximumCount represents the maximum number of concurrent quantities that can be used to set the maximum concurrency of the system, and if we set his value to 1,linitialcount is also set to 1, that is, there is only one resource that can be accessed by only one thread at a time, which enables thread synchronization.
4. When a thread leaves processing of a shared resource, it must increase the current available resource count through ReleaseSemaphore (). Otherwise, the actual number of threads that are currently working on the shared resource does not reach the value to limit, while other threads are still inaccessible because the current available resource count is 0.
The function prototypes for ReleaseSemaphore () are:
BOOL ReleaseSemaphore
(
HANDLE Hsemaphore,//semaphore handle
LONG lReleaseCount,//Count increment quantity
Lplong Lppreviouscount//Previous Count
);
This function adds the value in lReleaseCount to the current resource count for semaphores, typically sets lReleaseCount to 1, and optionally sets additional values if needed. WaitForSingleObject () and WaitForMultipleObjects () are primarily used in the entrance of a thread function attempting to enter a shared resource, primarily to determine whether the current available resource count for semaphores allows the entry of this thread. The monitored semaphore kernel object will be notified only if the current available resource count is greater than 0 o'clock.
5.
The difference between the mutex and the semaphore
(1). Mutexes are used for mutual exclusion of threads, and semaphores are used for thread synchronization.
This is the fundamental difference between the mutex and the semaphore, which is the difference between the mutex and the synchronization.
Mutex: Refers to a resource that allows only one visitor to access it, with uniqueness and exclusion. However, mutual exclusion cannot limit the order in which visitors access resources, that is, access is unordered.
Synchronization: Refers to the mutual exclusion of the basis (in most cases), through other mechanisms to achieve the visitor's orderly access to resources. In most cases, synchronization has been mutually exclusive, especially if all writes to the resource must be mutually exclusive. In rare cases, multiple visitors can be allowed to access resources at the same time.
The above difference is the main want to remember.
Note: semaphores can be used to implement the function of mutex
(2). The mutex value can only be 0/1, and the semaphore value may be a non-negative integer.
In other words, a mutex can only be used for mutually exclusive access to a resource, and it cannot implement multi-threaded mutex issues for multiple resources. The semaphore can realize multi-thread mutual exclusion and synchronization of multiple homogeneous resources. When the semaphore is a single-valued semaphore, it is also possible to complete a mutually exclusive access to a resource.
(3). The lock and unlock of the mutex must be used by the same thread, and the semaphore can be freed by one of the threads, and the other thread will get it.
Source code://Semaphore.cpp: Defines the entry point of the console application. //#include"stdafx.h"#include<Windows.h>#include<process.h>//Number of Threads#defineG_nthreadnum 5//Signal VolumeHANDLE G_HSP;//Cumulative NumberintG_ncount =0; unsigned _stdcall threadfunc (void*LParam) { for(inti =0; I <1000000; ++i) {//Enter the semaphore thresholdWaitForSingleObject (G_HSP, INFINITE); G_ncount++; //adds the specified value to the specified semaphore. Release semaphore CountReleaseSemaphore (G_HSP,1, NULL); } return 0;}int_tmain (intARGC, _tchar*argv[]) { //Create Semaphoreg_hsp= (HANDLE) CreateSemaphore (NULL,1,5, NULL); //Start ThreadHANDLE Pthread[g_nthreadnum]; for(inti =0; i < G_nthreadnum; ++i) {Pthread[i]= (HANDLE) _beginthreadex (NULL,0, ThreadFunc, NULL,0,0); if(Pthread[i] = =0) { Continue; I--; } } //wait for thread to endwaitformultipleobjects (G_nthreadnum, PThread, TRUE, INFINITE); printf ("g_ncount:%d\n", G_ncount); //Freeing Resources for(inti =0; i < G_nthreadnum; ++i) {CloseHandle (pthread[i]); } closehandle (G_HSP); GetChar (); return 0;}
Semaphore of thread synchronization