Ways between Linux thread synchronization

signal

Semaphore emphasized that the synchronization between threads (or processes): certain actions "semaphore used in a multi-threaded multi-task synchronization, a thread completes a certain action told by another thread semaphore, then another thread (everyone sem_wait time, it blocked there). when the value of a single semaphore semaphore can be done exclusive access to a resource. semaphore weighing the visitor orderly access to resources, in large in most cases, mutual exclusion synchronization has been achieved, especially in the case of writing all resources must be mutually exclusive. Rarely is one that can allow visitors to simultaneously access multiple resources.

Famous semaphore

It can be used for mutual exclusion between different processes or between multiple threads and synchronization

Create a well-known open semaphore

sem_t *sem_open(const char *name, int oflag);
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
//成功返回信号量指针;失败返回SEM_FAILED,设置errno

name is the file path name, but can not be written /tmp/a.sem this form, because in linux, sem are in the / dev / shm directory, can be written as "/ mysem" or "mysem", created out of the file are "/dev/shm/sem.mysem",mode to 0666, value set to the initial value of the semaphore already exists under the lights, and other conditions necessary to specify O_CREAT |. O_EXCL it was a mistake.

Close semaphores, when the process terminates, it calls

int sem_close(sem_t *sem);  //成功返回0;失败返回-1,设置errno

Delete semaphore, immediately delete the semaphore name, when other processes are closed it, destroy it

int sem_unlink(const char *name);

Waiting for the semaphore, the semaphore value of the test, if the value is less than or equal to 0, then wait (blocking); once its value becomes greater than 0 it will be decremented by 1, and returns

int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
//成功返回0;失败返回-1,设置errno

When the semaphore is 0, sem_trywait returns immediately, set errno EAGAIN. If a signal is interrupted, sem_wait prematurely returned, errno is set to EINTR

Issued a semaphore, to its value plus 1, and then wake up is waiting for the semaphore processes or threads

int sem_post(sem_t *sem);

Return 0 if successful; -1 failure, will not change its value, provided errno, which is an asynchronous signal safe function that can be called in signal processing program

Unnamed semaphore

For synchronization and mutual exclusion, using the following API (unnamed semaphore, based on the amount of memory of the signal) between the respective threads of a process in vivo

(1) sem_init
Function: a semaphore is used to create and initialize the value of the semaphore.
Prototype:     

int sem_init (sem_t* sem, int pshared, unsigned int value);

Function incoming values: sem: semaphore. pshared: determine whether the semaphore is shared among several processes. LINUX is not implemented due to the current inter-process shared information, so this can only take the value 0.

(2) Other functions

int sem_wait       (sem_t* sem);
int sem_trywait   (sem_t* sem);
int sem_post       (sem_t* sem);
int sem_getvalue (sem_t* sem);
int sem_destroy   (sem_t* sem);

Function: sem_wait and sem_trywait operation corresponding to P, they can decrease the value of a semaphore, the difference is that if the value of the semaphore is less than zero, the process of sem_wait will block, and sem_trywait returns immediately. V sem_post equivalent operation, it will add a value of the semaphore, the wake-up process also issued to the waiting (or threads).

sem_getvalue obtained semaphore value.

sem_destroy destroy semaphore.

If a memory-based lights are synchronized between different processes, the lights must be stored in a shared memory area, which should exist as long as the shared memory area, the lights there.

Mutex

Mutex (also known as mutex) emphasized that access to exclusive resources: mutex is used in a multi-threaded multi-tasking mutually exclusive, one thread occupy a certain resource, then other threads can not access until this thread unlock, other threads can begin to use this resource. Such as access to global variables, sometimes locked, the operation is over, unlocked. Sometimes locks and semaphores can be used simultaneously. In other words, the focus on a semaphore is not necessarily a resource, but the concept of the process, such as: There are A, B two threads, B, etc. A thread to thread then own the following steps after the completion of a task, this task is not necessarily a resource lock, it may also be some data processing or computing or the like. The thread mutex is the concept of "a lock resources", during the lock, other threads can not operate on the data to be protected. In some cases the two are interchangeable. 

In linux, mutex thread pthread_mutex_t data type before use, to initialize it:

For the mutex static allocation, you can set it to PTHREAD_MUTEX_INITIALIZER, or call pthread_mutex_init.

For the mutex dynamically allocated, after the application memory (malloc), initialized by pthread_mutex_init, and release memory (free) before you need to call pthread_mutex_destroy.

prototype:

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restric attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//返回值: 成功则返回0, 出错则返回错误编号.

Note: If you use the default initialization mutex attributes, simply attr to NULL value after the other to explain.

First talk about lock function:

head File:

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
//返回值: 成功则返回0, 出错则返回错误编号.

Description: specifically explain trylock function, which is a non-blocking call mode, that is, if the mutex is not locked, trylock function will lock mutex, and gain access to a shared resource; if mutually exclusive the amount is locked, trylock function will not block waiting for a direct return EBUSY, it represents the shared resource is busy.

To tell you the unlock function:

prototype:

int pthread_mutex_unlock(pthread_mutex_t *mutex);
//返回值: 成功则返回0, 出错则返回错误编号.

Condition variables often used in conjunction with a mutex, the thread to achieve synchronization purposes: Condition Variables up for the lack of a mutex by a method allowing the thread blocked waiting for another thread and the transmission signal. When the transmission signal, if no threads waiting on the condition variable, the signal will be lost; the semaphores have a count value, every time the amount of signal post operation is recorded.

  1. Who mutex must be locked to unlocked by whom, and semaphore wait and post operations need not be performed by the same thread.
  2. Either mutex is locked, or unwrapped, and two similar semaphore value
  3. sem_post is a function of various synchronization techniques, the only one can safely call in the signal handler
  4. Mutex is locked optimized; wait for the condition variable is optimized; semaphore for locking can also be used to wait, so there will be more overhead and complexity of higher
  5. Mutex, condition variables are only used between each thread in the process, and semaphore (semaphore famous) can be used for synchronization between different processes. When the semaphore for inter-process synchronization, semaphores requirements established in the shared memory area.
  6. Semaphore has a count value, every time the amount of signal post operation is recorded, and when the condition variable transmission signal, if there is no thread waiting for the condition variable, the signal will be lost.

Read-Write Lock

Write lock and mutex similar, but the read-write lock allows for higher parallelism. Mutex is locked or unlocked state is either state, but only one thread can lock it. Read-write lock may be formed of three states: state locking the read mode, write mode locked state, an unlocked state. Only one thread can occupy write mode read-write locks, but multiple threads can occupy read-write lock mode at the same time.

In the read-write lock is write locked state before the lock is unlocked, blocked all attempts to lock this thread will be locked. When the read-write lock in the locked state, all its attempts to read mode for locking thread can get access, but if you want to write mode this thread lock for locking, it must block until all the threads release read lock. Although read and write locks vary, but in read-write lock mode locked state, if there is another thread tries to lock in write mode, usually read-write lock will block the subsequent read mode lock requests. This avoids reading mode lock long-term occupation, while waiting for write mode lock request has not met.

Read-write lock is very suitable for the number of cases is much larger than the data structure read write. When the read-write lock down in write mode, it protects data structures can be safely modified, because the current only one thread can own the lock in write mode. When the read-write lock state, as long as the thread obtains a write lock in the read mode, the lock protected data structures may be a plurality of thread lock obtained read read mode.

Also known as shared read-write lock - exclusive lock, when the read-write lock to lock in read mode, it is locked in shared mode; when he was locked in write mode, it is locked in exclusive mode.

Initialization and destruction:

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
//成功则返回0, 出错则返回错误编号.

Same mutex or more, before releasing the occupied memory read-write lock, you need to clean up the work of read-write locks by pthread_rwlock_destroy, the release of resources allocated by init.

Read and write:

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
//成功则返回0, 出错则返回错误编号.

These three functions are achieved acquire a read lock, write lock acquire and release the lock function to get the operation of two locks are blocking operation, the same, non-blocking function:

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
//可以获取则返回0, 否则返回错误的EBUSY.

While the write lock increased parallelism, but no faster than the speed in terms of the mutex.

It is also possible even if there are still reasons to use mutex read-write locks exist, because he was slightly better in terms of speed. This requires us to consider the speed and parallelism when writing a program and find a compromise.

For example: Assuming mutex requires 0.5 seconds, 0.8 seconds required using read-write lock. In a similar type of student management system software, it may be ninety percent of the time query, so if now suddenly all 20 requests, if using a mutex, the last of the query request is satisfied after the required 10. In this way, it is estimated that no one can stand. The read-write locks, read locks should be able to obtain many times. Therefore, all 20 requests, each of about one second can
be met.

That is, in some places more or write operation itself is not much need to synchronize the programs we should use mutex, but much larger than the read write operation of the program, we should use read-write locks to synchronize

Condition variable (condition)

When used with the condition variable mutex, allowing the thread to wait for non-competitive manner specified conditions occur. Condition itself is protected by a mutex.

Thread must lock the mutex before changing the conditions of the state, other threads before obtaining a mutex is not aware of this change, it is necessary to calculate the condition after locking the mutex.

Detecting conditions is carried out under the protection mutex. If a condition is false, a thread is blocked automatically, and release the mutex wait state changes. If another thread has changed conditions, it signals to the associated condition variable, or a plurality of wake-up threads waiting for it to regain mutex, re-evaluation of the condition. If the two processes share the read-write memory, condition variables can be used to implement thread synchronization between these two processes.

1. Initialization

Data type pthread_cond_t condition variable is used, it must be initialized before use, which includes two ways:

Static: You can put constant PTHREAD_COND_INITIALIZER to statically allocated condition variable.

Dynamic: pthread_cond_init function, before the release of the memory space is a dynamic condition variable, use pthread_cond_destroy be cleaned.

int pthread_cond_init(pthread_cond_t *restrict cond, pthread_condattr_t *restrict attr);
int pthread_cond_destroy(pthread_cond_t *cond);
//成功则返回0, 出错则返回错误编号.

Note: The space occupied by the condition variable has not been released.

When pthread_cond_init attr parameter is NULL, it will create a default condition variable attributes; discussion after non-default.

2. Wait condition

int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restric mutex);
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict timeout);
//成功则返回0, 出错则返回错误编号.

These two functions are blocked waiting and waiting for a timeout.

Con wait wait condition becomes true, is passed to the mutex pthread_cond_wait the conditions for protection, the caller passes mutex locked to the function. Function to the calling thread is placed on the list of threads waiting for the condition, then mutual unlock exclusion amount, these two operations are atomic. this will shut down the conditions for checking the thread goes to sleep and wait for conditions to change the passage of time between these two operations, so that the thread will not miss any changing conditions.

When pthread_cond_wait return, the mutex is locked again.

pthread_cond_wait function's return value does not mean that conditions must change, must re-examine the value of the condition.

When pthread_cond_wait function returns, the corresponding current thread mutex is locked, even if the function returns an error.

After blocking a thread on the condition variable is awakened until pthread_cond_wait () function returns the value before conditions are likely to change. So after the function returns, before locking the respective mutex must be retested condition value. The best method is to cycle testing pthread_cond_wait function call, and to satisfy the conditional expression is set to the termination condition for the loop. Such as:

pthread_mutex_lock();
while (condition_is_false)
pthread_cond_wait();
pthread_mutex_unlock();

Different order blocked thread is released on the same condition variable is not necessarily.

Note: pthread_cond_wait () function is the exit point, if this function is called, has a pending request to withdraw and allow the thread exits, the thread will be terminated and started dealing with the aftermath function, but this time related variables and conditions mutex will remain in the locked state.

pthread_cond_timedwait function to a certain amount of time, even if the condition does not occur is unblocked. The time specified by the parameter abstime. When the function returns, the corresponding mutex is often locked, even if the function returns an error.

Note: pthread_cond_timedwait function is the exit point.

Timeout parameter is a certain time of day. Example of use:

pthread_timestruc_t to;
to.tv_sec = time(NULL) + TIMEOUT;
to.tv_nsec = 0;

Timeout error code returned is ETIMEDOUT.

3. Notification conditions

int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
//成功则返回0, 出错则返回错误编号.

These two functions are used to inform the threads have been met. These functions are called, also known as sending a signal to the thread or conditions. It must be noted, must give thread signals changing conditions in the future state.

[Original: http://blog.chinaunix.net/uid-20671208-id-4935154.html ]

Guess you like

Origin www.cnblogs.com/WindSun/p/11441234.html