Apue learning-POSIX thread (2)

Source: Internet
Author: User

A thread is the smallest unit of CPU scheduling, that is, multiple threads in a process are concurrently executed in an indefinite scheduling order. Multiple Threads in a process share memory resources. This introduces the concept of critical resources, resources that can be accessed by multiple threads, the code segment accessing critical resources in a thread is called a critical section. If multiple threads have critical zones of the same critical resource, the calling sequence of these threads may be different, at this time, we need some measures to make the thread execute in order according to our ideas to avoid this situation. This process is called thread synchronization.

The first method of thread synchronization is mutex. The mutex is actually a lock. The related operations are to lock before the critical section and unlock after the critical section. The mutex type is pthread_mutex_t.

The initialization and destruction of this type include static and dynamic methods. The static method is simple: pthread_mutex_t mutex = pthread_mutex_initializer; the dynamic method is to use the pthread_mutex_init () and pthread_mutex_destroy () functions.

 

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);int pthread_mutex_destory(pthread_mutex_t *mutex);

The difference between the two methods is that the second method can specify the mutex attribute. If the default attribute is null.

 

The lock and unlock operations are as follows:

 

int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex);

The pthread_mutex_lock () function is a lock operation. If the mutex lock is in the unlocked state, the lock is successfully executed. Otherwise, the function will be blocked until the lock can be applied. The pthread_mutex_unlock () function is an unlock operation. If the lock status is locked, an error is returned. The function of the pthread_mutex_trylock () function is to try to lock. If the lock is in the locked State and does not block, it returns ebusy. This function is generally used to access the critical zone when the lock is applied or another operation is executed.

 

The critical resource here is not limited to the resources that every thread can access, but also some other resources used in the process, such as files. The code used to access the same file in multiple threads is also a critical section, so mutex is also required. The Linux system also provides different operating functions for existing files (the principle is to use mutex ).

 

void flockfile(FILE *filehandle);int ftrylockfile(FILE *filehandle);void funlockfile(FILE *filehandle);  

The functions and usage of these three functions are the same as those of the mutex lock unlock operation.

The same function can be called in multiple threads. The pthread_once () function can be used to specify the function to be called only once in all threads (which call is not necessarily)

int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));pthread_once_t once_control = PTHREAD_ONCE_INIT;

Pthread_once () is used to call the init_routine function and ensure that it is called only once throughout the process.

 

There is also a kind of lock similar to the processing capacity-read/write locks. The difference between read/write locks and mutex locks is that there are two types of locks applied to the critical section: Shared read locks and exclusive write locks, if you only perform read operations on critical resources in the critical section, you can use the read lock. Otherwise, you need to write the lock. Multiple read locks can be added, but only one write lock can be added (and no read lock is allowed ). Perform the following operations:

 

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZE;int pthread_rwlock_init(pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr);int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);int pthread_rwlock_rwlock(pthread_rwlock_t *rwlock);int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

All operations and mutex are similar here. Note that there can be only one write lock at a time, and there can be no read lock or an unlimited number of read locks.
The mutex is often used together with the condition variable. The condition variable is not a lock, but a waiting-notification mechanism. Waiting is a condition, notifying is that conditions are met, and providing a way to wait for conditions between threads. The condition variable type is pthread_cond_t. the initialization and destruction operations are as follows:

 

 

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;int pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t *attr); int pthread_cond_destroy(pthread_cond_t *cond);   

The operation on the condition variable is waiting and notification, and is used for the function of waiting for the condition:

 

 

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t  *mutex);int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t*mutex, const struct timespec * timeout);

The functions of the pthread_cond_wait () function are divided into three steps: 1. Unlock mutex 2. Wait for the notification condition to reach 3. Unlock mutex; the thread is in the blocking state while waiting for the notification. Compared with the pthread_cond_timedwait () function and the pthread_cond_wait () function, the pthread_cond_wait () function has a time structure that is used for time-out. If this time is exceeded during the Second-Step Blocking, the returned error code is etimedout. Note that this time is not a time period but a time point.

 

The notification condition fulfillment function is as follows:

 

int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_signal(pthread_cond_t *cond);

This function is used to notify other threads that the conditions are met and remove the blocking in step 2. In this way, the notified thread can attempt to lock the thread again and continue to execute the function. The difference between the two functions is: pthread_cond_signal () is used to notify all threads in the wait state to unblocking and try to lock, while pthread_cond_broadcast () it is used to notify all threads in the wait status to unblocking and try to lock. The programmer determines when a notification is sent and the notification must be sent after the condition is reached. If the condition has been reached before wait, it is possible that wait will wait forever (the notifications sent will not be retained until they are accepted ).

 

The last synchronization method is to use the unknown semaphores. Semaphores are also called Signal lights. When lights are on, they indicate that resources can be used (you can enter the critical section). When lights are off, they indicate that no resources are available (not blocked in the critical section). semaphores are multiple lamps, that is to say, the number of lights can be multiple, but as long as there is a bright light, you can enter the critical area; each time you enter the critical area, you should turn out a light, and each time you exit the critical area, you should turn on a light. The related operations are as follows:

 

int sem_init(sem_t *sem, int pshared, unsigned int value); int sem_destroy(sem_t *sem);int sem_wait(sem_t *sem); int sem_post(sem_t *sem); int sem_getvalue(sem_t *sem, int *sval);

The sem_init () function is used to initialize a semaphore. pshared is 0 for inter-thread, non-0 for inter-process, and the value parameter is the number of initialization lights. The sem_destroy () function is used to destroy a semaphore. The sem_wait () function is used to extinguish the lamp. If no lamp is available, it is blocked until the lamp is on again. The sem_post () function is used to enable the lamp. The setm_getvalue () function is used to obtain the number of lights.

 

What we have to mention is the concept of deadlock. Deadlock: Two or more threads (processes) Wait for each other due to competing resources during execution. Cause of deadlock: The resource competition and the thread (process) Promotion order are invalid. Conditions for deadlock generation: mutex conditions, request and persistence conditions, non-deprivation conditions, and loop wait conditions. Deadlock handling method: prevent deadlocks (any of the damage conditions) and avoid deadlocks (shorten the transaction's logical processing process, deadlock timeout, optimization program, careful testing, and error handling)

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.