In Windows, in order to synchronize multiple threads, we usually have to ensure that only one thread can be used for the use of global variables and other resources, A thread cannot use this variable for other threads before it is declared to be released. In Windows, we can use the entercriticalsection () and leavecriticalsection () functions. What is the similar mechanism in Linux?
The mutex lock is introduced here.
1. Apply for a mutex lock
Pthread_mutex_t mutex; // apply for a mutex lock
You can declare multiple mutex.
After declaring this variable, you need to call pthread_mutex_init ()To create the variable.Pthread_mutex_initThe format is as follows:
Int pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexAttr_t * mutexattr );
The first parameter,MutextThat is, the mutex you previously declared. The second parameter is the attribute of the mutex. Attributes are defined as follows:
The mutex can be divided into the following three types:
LFast (Pthread_mutex_fast_np). This type is also the default type. The thread behavior is as mentioned above.
L recursive type ( pthread_mutex_recursive_np ). If the deadlock we mentioned above occurs and the same thread loops to lock mutex, the system will know that the lock behavior comes from the same thread, then the thread will agree to lock the mutex.
LError Detection type (Pthread_mutex_errorcheck_np). If the mutex has been locked, subsequent locks will fail without blocking,Pthread_mutex_lock ()The Operation will returnEdeadlk.
Function
Note that the following statements can quickly initialize a mutex lock to a fast type.
Pthread_mutex_t mutex = pthread_mutex_initializer;
2. Destroy a mutex lock
Pthread_mutex_destroy () is used to cancel a mutex lock. The API is defined as follows:
Int pthread_mutex_destroy (pthread_mutex_t * mutex)
Destroying a mutex lock means releasing the resources it occupies and requires the lock to be open. In Linux, mutex locks do not occupy any resources. Therefore, pthread_mutex_destroy () in linuxthreads has no action except checking the lock status (ebusy is returned when the lock status is locked.
3. Lock (equivalent to entercriticalsection in Windows)
After creating the mutex, you can use it. To obtain the mutex, you need to call the following function:
Int pthread_mutex_lock (pthread_mutex_t * mutex );
This function is used to lock the mutex. Once the mutex is locked, if other threads want to lock the mutex, the operation will be blocked. If the mutex has been locked by other threads before, the operation will be blocked until the lock is obtained.
After obtaining the mutex, you can enter the keyCodeZone.
4. Unlock (equivalent to leavecriticalsection in Windows)
After the operation is complete, you must call the following function to unlock the mutex, that is, release. In this way, other threads waiting for the lock will have the opportunity to obtain the lock, Otherwise other threads will be blocked forever.
Int pthread_mutex_unlock (pthread_mutex_t * mutex );
5. pthread_mutex_trylock
If we don't want to block it all the time, we can call the following function:
Int pthread_mutex_trylock (Pthread_mutex_t * mutex)
If the mutex is not locked at this timePthread_mutex_trylock ()Will return0And lock the mutex. If the mutex is locked, return immediatelyEbusy.
The sample code is as follows:
# Include<Malloc. h>
# Include<Pthread. h>
StructJob {
/*Link field for linked list.*/
StructJob*Next;
/*Other fields describing work to be done*/
};
/*A linked list of pending jobs.*/
StructJob*Job_queue;
/*A mutex protecting job_queue.*/
Pthread_mutex_t job_queue_mutex=Pthread_mutex_initializer;
/*Process queued jobs until the queue is empty.*/
Void*Thread_function (Void*Arg)
{
While(1){
StructJob*Next_job;
/*Lock the mutex on the job queue.*/
Pthread_mutex_lock (&Job_queue_mutex );
/*Now it's safe to check if the queue is empty.*/
If(Job_queue=Null)
Next_job=NULL;
Else{
/*Get the next available job.*/
Next_job=Job_queue;
/*Remove this job from the list.*/
Job_queue=Job_queue->Next;
}
/*Unlock the mutex on the Job Queue because we're re done with
Queue for now.*/
Pthread_mutex_unlock (&Job_queue_mutex );
/*Was the queue empty? If so, end the thread.*/
If(Next_job=Null)
Break;
/*Carry out of the work.*/
Process_job (next_job );
/*Clean up.*/
Free (next_job );
}
ReturnNULL;
}