Mutex is a key. When a person takes the key, they can enter a room. When they come out, the key is handed over to the first in the queue. Generally, this method is used to serialize the access to the critical section code to ensure that the Code is not run in parallel.
Semaphore is a room that can accommodate n people. If not, you can enter the room. If the person is full, you have to wait for someone to come out. For n = 1, it is called binary semaphore. It is generally used to restrict simultaneous access to a resource.
Differences between binary semaphore and mutex:
In some systems, binary semaphore and mutex are not different. In some systems, the main difference is that mutex must be released by the process that acquires the lock. The semaphore can be released by other processes (in this case, semaphore is actually an atomic variable, which can be added or subtracted). Therefore, semaphore can be used for inter-process synchronization. The synchronization function of semaphore is supported by all systems, and whether mutex can be released by other processes is not fixed. Therefore, we recommend that mutex only protect the critical section. Semaphore is used to protect a variable or synchronize data.[CPP]
View plaincopy
- Class semaphore
- {
- Public:
- Semaphore (INT count, int max_count );
- ~ Semaphore ();
- Void unsignal (); // wait for the P, count -- operation. If Count = 0, wait.
- Void signal (); // release operation V, Count ++
- }
- Classmutex
- {
- Public:
- Waitmutex (); // blocks the thread until other threads release the mutex lock.
- Releasemutex (); // release a thread
- }
Another concept is spin lock, which is a kernel state concept. The main difference between spin lock and semaphore is that spin lock is busy waiting, while semaphore is sleep. Busy waiting is meaningless for sleep processes. For a single CPU system, busy waiting is of course meaningless (no CPU can release the lock ). Therefore, spin lock is used only for multi-CPU kernel-State non-process space. In the case of non-SMP, the Linux kernel spin lock only shuts down IRQ and has no other operations. It is used to ensure that the running of this program will not be interrupted. In fact, this is similar to mutex's function.
Critical section access. However, mutex cannot protect the interruption or be called in the interrupt processing program. The spin lock is generally not necessary for sleep process space.
Bytes ---------------------------------------------------------------------------------------------
Kernel synchronization measures
To avoid concurrency and prevent competition. The kernel provides a set of Synchronization Methods to protect shared data. Our focus is not to introduce the detailed usage of these methods, but to emphasize the difference between these methods and them.
The synchronization mechanism used in Linux has been continuously improved since 2.0 to 2.6. From the initial atomic operation to the subsequent semaphores, from the large kernel lock to today's spin lock. The development of these synchronization mechanisms is accompanied by the overprovisioning of Linux from a single processor to a symmetric multi-processor, and the overprovisioning of a non-preemptible kernel to a preemptible kernel. The locking mechanism becomes more effective and more complex.
Currently, sub-operations in the kernel are mostly used for counting. In other cases, two locks and their variants are most commonly used: one is the spin lock and the other is the semaphore. We will introduce the two lock mechanisms below.
Spin lock
The spin lock is a kind of lock introduced to prevent multi-processor concurrency. It is widely applied to interrupt processing and other parts in the kernel (for single processor, to prevent the concurrency in the interrupt processing, you can simply disable the interrupt without the need to spin the lock ).
A spin lock can only be held by one kernel task at most. If a kernel task attempts to request a spin lock that has been used (held, then this task will always be busy loop-rotate-Wait for the lock to be available again. If the lock is not in contention, the kernel task requesting it will immediately get it and continue. The spin lock can prevent more than one kernel task from entering the critical section at any time. Therefore, this lock can effectively avoid competition for shared resources for Kernel Tasks running concurrently on the multi-processor.
In fact, the intention of the spin lock is to implement lightweight locking in a short period of time. A competing spin lock allows the thread requesting it to spin while waiting for the lock to be available again (especially wasting processing time), so the spin lock should not be held for too long. If you need to lock for a long time, it is best to use a semaphore.
The basic form of the spin lock is as follows:
Spin_lock (& mr_lock );
// Critical section
Spin_unlock (& mr_lock );
Because the spin lock can only be held by up to one kernel task at a time point, only one thread is allowed to exist in the critical section at a time point. This satisfies the locking service required by Symmetric Multi-processing machines. On a single processor, the spin lock is only used as a switch to set kernel preemption. If the kernel preemptible does not exist, the spin lock will be completely removed from the kernel during compilation.
To put it simply, spin locks are mainly used in the kernel to prevent concurrent access to the critical zone in the multi-processor and to prevent competition caused by kernel preemption. In addition, the spin lock does not allow the task to sleep (sleep of a task holding the spin lock will cause an automatic deadlock-Because sleep may cause the kernel task holding the lock to be rescheduled, apply for a lock that you already hold), which can be used in the interrupt context.
Deadlock: Assume one or more kernel tasks and one or more resources. Each kernel is waiting for one of these resources, but all resources are occupied. In this case, all kernel tasks are waiting for each other, but they will never release the occupied resources. Therefore, no kernel task can obtain the required resources and continue running, this means that the deadlock has occurred. Self-occupation means that you possess a certain resource, and then apply for the resource that you already possess. Obviously, it is impossible to obtain the resource again.
Semaphores
Semaphores in Linux are sleep locks. If a task tries to obtain an held semaphore, the semaphore will push it into the waiting queue and then sleep it. In this case, the processor is free to execute other code. When the process holding the semaphore releases the semaphore, a task in the waiting queue will be awakened to obtain the semaphore.
The sleep feature of semaphores makes the semaphores suitable for cases where the lock is held for a long time. They can only be used in the process context because the interrupt context cannot be scheduled; in addition, when the Code holds a semaphore, it cannot hold a spin lock.
The basic usage of semaphores is as follows:
Static declare_mutex (mr_sem); // declare mutex semaphores
If (down_interruptible (& mr_sem ))
// Interrupted sleep. When the signal arrives, the sleep task is awakened.
// Critical section
Up (& mr_sem );
Differences between semaphores and spin locks
Although the conditions for use between the two are complex, in fact, in actual use, semaphores and spin locks are not easy to confuse. Note the following principles:
If the code needs to sleep-this often happens when it is synchronized with the user space-using semaphores is the only option. Because it is not restricted by sleep, it is generally easier to use semaphores. If you need to choose between the spin lock and semaphore, it depends on the length of time the lock was held. Ideally, all locks should be held as short as possible, but it is better to use semaphores if they are held for a long time. In addition, unlike the spin lock, semaphores do not disable kernel preemption, so the code holding semaphores can be preemptible. This means that the semaphore will not have a negative impact on the scheduling response time.
Semaphores
Requirement Recommended locking method
Lock with low overhead Use spin lock first
Short-term lock Use spin lock first
Long-term lock Use semaphores first
Locks interrupt Context Use spin lock
Holding locks requires sleep and scheduling. Use semaphores
Bytes ---------------------------------------------------------------------------------------------
Critical Section)
A convenient way to ensure that only one thread can access data at a certain time point. Only one thread is allowed to access Shared resources at any time. If multiple threads attempt to access the critical section at the same time, all other threads attempting to access the critical section will be suspended and will continue until the thread enters the critical section. After the critical section is released, other threads can continue to seize it and use the atomic method to share resources.
When a critical section is used, it is generally not allowed to run for a long time. As long as the thread entering the critical section has not left, all other threads attempting to enter the critical section will be suspended and enter the waiting state, and will be affected to a certain extent. Program running performance. In particular, do not include operations waiting for user input or other external interventions in the critical section. If you enter the critical section but have not been released, it will also cause other threads to wait for a long time. Although the synchronization speed in the critical section is very fast, it can only be used to synchronize threads in the current process, but not to synchronize threads in multiple processes.
Mutex)
Mutex is a kernel object that is widely used. Multiple Threads can access the same shared resource mutex. Similar to the critical section, only threads with mutex objects have the permission to access resources. Because there is only one mutex object, therefore, it is determined that the shared resource will not be accessed by multiple threads at the same time under any circumstances. The thread occupying the resource should hand over the mutex object after the task is processed, so that other threads can access the resource after obtaining it. Unlike other kernel objects, mutex objects have special code in the operating system and are managed by the operating system, the operating system even allows it to perform unconventional operations that are not allowed by other kernel objects. The mutex is similar to that in the critical section. Only threads with mutex objects have the permission to access resources. Because there is only one mutex object, therefore, it is determined that the shared resource will not be accessed by multiple threads at the same time under any circumstances. The thread occupying the resource should hand over the mutex object after the task is processed, so that other threads can access the resource after obtaining it. Mutex is more complex than that in the critical section. Because mutex can not only achieve secure resource sharing in different threads of the same application, but also achieve secure resource sharing among threads of different applications.
Semaphores)
The method for synchronizing semaphore objects to threads is different from the previous methods. Signals allow multiple threads to use shared resources at the same time, which is the same as PV operations in the operating system. It specifies the maximum number of threads simultaneously accessing shared resources. It allows multiple threads to access the same resource at the same time, but it needs to limit the maximum number of threads that can access the resource at the same time. When using createsemaphore () to create a semaphore, you must specify the maximum allowed resource count and the current available resource count. Generally, the current available resource count is set to the maximum Resource Count. Each time a thread is added to access a shared resource, the current available resource count is reduced by 1, as long as the current available resource count is greater than 0, a semaphore signal can be sent. However, when the current available count is reduced to 0, it indicates that the number of threads currently occupying resources has reached the maximum allowed number, and other threads cannot enter, at this time, the semaphore signal cannot be sent. After processing shared resources, the thread should use the releasesemaphore () function to increase the number of currently available resources by 1 while leaving. The current available resource count cannot exceed the maximum resource count at any time. Semaphores control thread access resources by counting. In fact, semaphores are also called Dijkstra counters.
PV operations and semaphores are all proposed by Dutch scientist E. W. Dijkstra. Semaphore s is an integer. When S is greater than or equal to zero, the number of resource entities available for concurrent processes in the table. If S is less than zero, it indicates the number of processes waiting to use shared resources.
P operation resource application:
(1) s minus 1;
(2) If s minus 1 is still greater than or equal to zero, the process continues to run;
(3) If s minus 1 is less than zero, the process is blocked and enters the queue corresponding to the signal, and then transferred to the process scheduling.
V operation to release resources:
(1) s plus 1;
(2) If the sum result is greater than zero, the process continues to execute;
(3) If the sum result is less than or equal to zero, a waiting process is awakened from the waiting queue of the signal, and then the original process is returned for further execution or transfer to process scheduling.
The usage of semaphores makes it more suitable for synchronization of threads in socket (socket) programs. For example, if the HTTP server on the network needs to limit the number of users who access the same page at the same time, you can set a thread for none of the users to request the page on the server, the page is the shared resource to be protected. By using semaphores to synchronize threads, users can access a page no matter how many users at any time, only threads with the maximum number of users can access this page, while other access attempts are suspended. This page can only be accessed after a user exits.
Summary:
1. The mutex function is very similar to that of the critical zone, but the mutex can be named, that is, it can be used across processes. Therefore, creating mutex requires more resources. Therefore, if you only use it within a process, using the critical section will bring speed advantages and reduce resource occupation. Because the mutex is a cross-process mutex, once created, it can be opened by name.
2. mutex and semaphore can all be used by a process to synchronize data. Other objects are irrelevant to the data synchronization operation, but for processes and threads, if the process and thread are in the running status, there is no signal, and there is a signal after exiting.
3. you can specify how resources are exclusive by means of mutex. However, if the following problem occurs, the resource cannot be processed by means of mutex, for example, if a user buys a database system with three concurrent access licenses, the user can decide how many threads/processes can perform database operations at the same time based on the number of access licenses purchased by the user, at this time, if the mutex is used, there is no way to fulfill this requirement. The traffic signal object can be said to be a resource counter.
Mutex is a key. When a person takes the key, they can enter a room. When they come out, the key is handed over to the first in the queue. Generally, this method is used to serialize the access to the critical section code to ensure that the Code is not run in parallel.
Semaphore is a room that can accommodate n people. If not, you can enter the room. If the person is full, you have to wait for someone to come out. For n = 1, it is called binary semaphore. It is generally used to restrict simultaneous access to a resource.
Differences between binary semaphore and mutex:
In some systems, binary semaphore and mutex are not different. In some systems, the main difference is that mutex must be released by the process that acquires the lock. The semaphore can be released by other processes (in this case, semaphore is actually an atomic variable, which can be added or subtracted). Therefore, semaphore can be used for inter-process synchronization. The synchronization function of semaphore is supported by all systems, and whether mutex can be released by other processes is not fixed. Therefore, we recommend that mutex only protect the critical section. Semaphore is used to protect a variable or synchronize data.[CPP]
View plaincopy
- Class semaphore
- {
- Public:
- Semaphore (INT count, int max_count );
- ~ Semaphore ();
- Void unsignal (); // wait for the P, count -- operation. If Count = 0, wait.
- Void signal (); // release operation V, Count ++
- }
- Classmutex
- {
- Public:
- Waitmutex (); // blocks the thread until other threads release the mutex lock.
- Releasemutex (); // release a thread
- }
Another concept is spin lock, which is a kernel state concept. The main difference between spin lock and semaphore is that spin lock is busy waiting, while semaphore is sleep. Busy waiting is meaningless for sleep processes. For a single CPU system, busy waiting is of course meaningless (no CPU can release the lock ). Therefore, spin lock is used only for multi-CPU kernel-State non-process space. In the case of non-SMP, the Linux kernel spin lock only shuts down IRQ and has no other operations. It is used to ensure that the running of this program will not be interrupted. In fact, this is similar to mutex's function.
Critical section access. However, mutex cannot protect the interruption or be called in the interrupt processing program. The spin lock is generally not necessary for sleep process space.
Bytes ---------------------------------------------------------------------------------------------
Kernel synchronization measures
To avoid concurrency and prevent competition. The kernel provides a set of Synchronization Methods to protect shared data. Our focus is not to introduce the detailed usage of these methods, but to emphasize the difference between these methods and them.
The synchronization mechanism used in Linux has been continuously improved since 2.0 to 2.6. From the initial atomic operation to the subsequent semaphores, from the large kernel lock to today's spin lock. The development of these synchronization mechanisms is accompanied by the overprovisioning of Linux from a single processor to a symmetric multi-processor, and the overprovisioning of a non-preemptible kernel to a preemptible kernel. The locking mechanism becomes more effective and more complex.
Currently, sub-operations in the kernel are mostly used for counting. In other cases, two locks and their variants are most commonly used: one is the spin lock and the other is the semaphore. We will introduce the two lock mechanisms below.
Spin lock
The spin lock is a kind of lock introduced to prevent multi-processor concurrency. It is widely applied to interrupt processing and other parts in the kernel (for single processor, to prevent the concurrency in the interrupt processing, you can simply disable the interrupt without the need to spin the lock ).
A spin lock can only be held by one kernel task at most. If a kernel task attempts to request a spin lock that has been used (held, then this task will always be busy loop-rotate-Wait for the lock to be available again. If the lock is not in contention, the kernel task requesting it will immediately get it and continue. The spin lock can prevent more than one kernel task from entering the critical section at any time. Therefore, this lock can effectively avoid competition for shared resources for Kernel Tasks running concurrently on the multi-processor.
In fact, the intention of the spin lock is to implement lightweight locking in a short period of time. A competing spin lock allows the thread requesting it to spin while waiting for the lock to be available again (especially wasting processing time), so the spin lock should not be held for too long. If you need to lock for a long time, it is best to use a semaphore.
The basic form of the spin lock is as follows:
Spin_lock (& mr_lock );
// Critical section
Spin_unlock (& mr_lock );
Because the spin lock can only be held by up to one kernel task at a time point, only one thread is allowed to exist in the critical section at a time point. This satisfies the locking service required by Symmetric Multi-processing machines. On a single processor, the spin lock is only used as a switch to set kernel preemption. If the kernel preemptible does not exist, the spin lock will be completely removed from the kernel during compilation.
To put it simply, spin locks are mainly used in the kernel to prevent concurrent access to the critical zone in the multi-processor and to prevent competition caused by kernel preemption. In addition, the spin lock does not allow the task to sleep (sleep of a task holding the spin lock will cause an automatic deadlock-Because sleep may cause the kernel task holding the lock to be rescheduled, apply for a lock that you already hold), which can be used in the interrupt context.
Deadlock: Assume one or more kernel tasks and one or more resources. Each kernel is waiting for one of these resources, but all resources are occupied. In this case, all kernel tasks are waiting for each other, but they will never release the occupied resources. Therefore, no kernel task can obtain the required resources and continue running, this means that the deadlock has occurred. Self-occupation means that you possess a certain resource, and then apply for the resource that you already possess. Obviously, it is impossible to obtain the resource again.
Semaphores
Semaphores in Linux are sleep locks. If a task tries to obtain an held semaphore, the semaphore will push it into the waiting queue and then sleep it. In this case, the processor is free to execute other code. When the process holding the semaphore releases the semaphore, a task in the waiting queue will be awakened to obtain the semaphore.
The sleep feature of semaphores makes the semaphores suitable for cases where the lock is held for a long time. They can only be used in the process context because the interrupt context cannot be scheduled; in addition, when the Code holds a semaphore, it cannot hold a spin lock.
The basic usage of semaphores is as follows:
Static declare_mutex (mr_sem); // declare mutex semaphores
If (down_interruptible (& mr_sem ))
// Interrupted sleep. When the signal arrives, the sleep task is awakened.
// Critical section
Up (& mr_sem );
Differences between semaphores and spin locks
Although the conditions for use between the two are complex, in fact, in actual use, semaphores and spin locks are not easy to confuse. Note the following principles:
If the code needs to sleep-this often happens when it is synchronized with the user space-using semaphores is the only option. Because it is not restricted by sleep, it is generally easier to use semaphores. If you need to choose between the spin lock and semaphore, it depends on the length of time the lock was held. Ideally, all locks should be held as short as possible, but it is better to use semaphores if they are held for a long time. In addition, unlike the spin lock, semaphores do not disable kernel preemption, so the code holding semaphores can be preemptible. This means that the semaphore will not have a negative impact on the scheduling response time.
Semaphores
Requirement Recommended locking method
Lock with low overhead Use spin lock first
Short-term lock Use spin lock first
Long-term lock Use semaphores first
Locks interrupt Context Use spin lock
Holding locks requires sleep and scheduling. Use semaphores
Bytes ---------------------------------------------------------------------------------------------
Critical Section)
A convenient way to ensure that only one thread can access data at a certain time point. Only one thread is allowed to access Shared resources at any time. If multiple threads attempt to access the critical section at the same time, all other threads attempting to access the critical section will be suspended and will continue until the thread enters the critical section. After the critical section is released, other threads can continue to seize it and use the atomic method to share resources.
When a critical section is used, it is generally not allowed to run for a long time. As long as the thread entering the critical section has not left, all other threads attempting to enter the critical section will be suspended and enter the waiting state, and will be affected to a certain extent. Program running performance. In particular, do not include operations waiting for user input or other external interventions in the critical section. If you enter the critical section but have not been released, it will also cause other threads to wait for a long time. Although the synchronization speed in the critical section is very fast, it can only be used to synchronize threads in the current process, but not to synchronize threads in multiple processes.
Mutex)
Mutex is a kernel object that is widely used. Multiple Threads can access the same shared resource mutex. Similar to the critical section, only threads with mutex objects have the permission to access resources. Because there is only one mutex object, therefore, it is determined that the shared resource will not be accessed by multiple threads at the same time under any circumstances. The thread occupying the resource should hand over the mutex object after the task is processed, so that other threads can access the resource after obtaining it. Unlike other kernel objects, mutex objects have special code in the operating system and are managed by the operating system, the operating system even allows it to perform unconventional operations that are not allowed by other kernel objects. The mutex is similar to that in the critical section. Only threads with mutex objects have the permission to access resources. Because there is only one mutex object, therefore, it is determined that the shared resource will not be accessed by multiple threads at the same time under any circumstances. The thread occupying the resource should hand over the mutex object after the task is processed, so that other threads can access the resource after obtaining it. Mutex is more complex than that in the critical section. Because mutex can not only achieve secure resource sharing in different threads of the same application, but also achieve secure resource sharing among threads of different applications.
Semaphores)
The method for synchronizing semaphore objects to threads is different from the previous methods. Signals allow multiple threads to use shared resources at the same time, which is the same as PV operations in the operating system. It specifies the maximum number of threads simultaneously accessing shared resources. It allows multiple threads to access the same resource at the same time, but it needs to limit the maximum number of threads that can access the resource at the same time. When using createsemaphore () to create a semaphore, you must specify the maximum allowed resource count and the current available resource count. Generally, the current available resource count is set to the maximum Resource Count. Each time a thread is added to access a shared resource, the current available resource count is reduced by 1, as long as the current available resource count is greater than 0, a semaphore signal can be sent. However, when the current available count is reduced to 0, it indicates that the number of threads currently occupying resources has reached the maximum allowed number, and other threads cannot enter, at this time, the semaphore signal cannot be sent. After processing shared resources, the thread should use the releasesemaphore () function to increase the number of currently available resources by 1 while leaving. The current available resource count cannot exceed the maximum resource count at any time. Semaphores control thread access resources by counting. In fact, semaphores are also called Dijkstra counters.
PV operations and semaphores are all proposed by Dutch scientist E. W. Dijkstra. Semaphore s is an integer. When S is greater than or equal to zero, the number of resource entities available for concurrent processes in the table. If S is less than zero, it indicates the number of processes waiting to use shared resources.
P operation resource application:
(1) s minus 1;
(2) If s minus 1 is still greater than or equal to zero, the process continues to run;
(3) If s minus 1 is less than zero, the process is blocked and enters the queue corresponding to the signal, and then transferred to the process scheduling.
V operation to release resources:
(1) s plus 1;
(2) If the sum result is greater than zero, the process continues to execute;
(3) If the sum result is less than or equal to zero, a waiting process is awakened from the waiting queue of the signal, and then the original process is returned for further execution or transfer to process scheduling.
The usage of semaphores makes it more suitable for synchronization of threads in socket (socket) programs. For example, if the HTTP server on the network needs to limit the number of users who access the same page at the same time, you can set a thread for none of the users to request the page on the server, the page is the shared resource to be protected. By using semaphores to synchronize threads, users can access a page no matter how many users at any time, only threads with the maximum number of users can access this page, while other access attempts are suspended. This page can only be accessed after a user exits.
Summary:
1. The mutex function is very similar to that of the critical zone, but the mutex can be named, that is, it can be used across processes. Therefore, creating mutex requires more resources. Therefore, if you only use it within a process, using the critical section will bring speed advantages and reduce resource occupation. Because the mutex is a cross-process mutex, once created, it can be opened by name.
2. mutex and semaphore can all be used by a process to synchronize data. Other objects are irrelevant to the data synchronization operation, but for processes and threads, if the process and thread are in the running status, there is no signal, and there is a signal after exiting.
3. you can specify how resources are exclusive by means of mutex. However, if the following problem occurs, the resource cannot be processed by means of mutex, for example, if a user buys a database system with three concurrent access licenses, the user can decide how many threads/processes can perform database operations at the same time based on the number of access licenses purchased by the user, at this time, if the mutex is used, there is no way to fulfill this requirement. The traffic signal object can be said to be a resource counter.