Linux Advanced Programming Fundamentals Series: Inter-thread communication

Source: Internet
Author: User
Tags function prototype mutex

Linux Advanced Programming Fundamentals Series: Inter-thread communication

Reprint: Original Address http://blog.163.com/jimking_2010/blog/static/1716015352013102510748824/

Inter-thread communication mechanism:

Threading is a lightweight process. the communication mechanism of the process mainly includes nameless pipes, famous pipelines, message queues, semaphores, shared memory, and Signals . These mechanisms are maintained by the Linux kernel, are complex to implement, and take up a lot of system resources. the communication mechanism between threads is relatively simple to implement, including mutex, condition variable, read-write lock and thread signal , etc. This article expands on the communication mechanism between the threads involved. Mutual exclusion Lock communication mechanism:1, Mutual exclusion lock basic principle : Mutex in an exclusive way to prevent data from being modified concurrently. When multiple threads share the same memory, you need to make sure that each thread sees the same data. If it is read-only, then it must be the same. If it is readable and writable, it contains three steps to read the data, modify the data, and write back the data when a thread operates a memory area. If the thread does not write back to the data, another thread accesses the same area, if it is read, does not get the latest data state, and if it is written, it can cause data overwrite and so on. the mutex is in two states: Unlock (0), lock (1). After you bind a shared resource and a mutex, access to the shared resource is as follows:a "before accessing the resource, first apply for the mutex, if in the unlocked state, then apply to the lock object, and immediately occupy the lock (lock). In case other threads access modify this resource. If the lock is locked, the default block waits. B "In principle only the process that locks the mutex can release this mutex. But in fact, a non-locking thread will be able to unlock it. This is related to the condition of the lock, which is described in detail later in this article. The mutex basic operation function is as follows:function function Initialize Mutex lock pthread_mutex_init () blocking request Mutex Pthread_mutex_lock () Release Mutex lock pthread_mutex_unlock () try locking (non-blocking mode) Pthread_mutex_trylock () Destroy Mutex lock Pthread_mutex_destroy () 2, the mutual exclusion lock initialization and destruction: Pthread_mutex_init (), Pthread_mutex_destroy () A "header file: #include <pthread.h>B "function prototype: extern int pthread_mutex_init (pthread_mutex_t *__mutex,__const pthread_mutexattr_t *__mutexattr);extern int Pthread_mutex_destroy (pthread_mutex_t *__mutex); C "Return: Operation successfully returns 0, non-0 value returned if unsuccessfulD "parameter:A, the first parameter is a pointer to the mutex to initialize/destroy. Pthread_mutex_t is the mutex type. When using mutexes, you define a variable of this type within the function. Its value can be initialized by the Pthread_mutex_init () function, or by using the macro Pthread_mutex_initializer defined in Pthread.h (only for statically allocated mutexes). if the mutex is dynamically allocated, it needs to be initialized with Pthread_mutex_init () before releasing the memory Pthread_mutex_destroy. the PTHREAD.H macro is defined as follows:#define Pthread_mutex_initializer {{0,}}The initialization method is as follows:pthread_mutex_t p = pthread_mutex_initializer;B, the second parameter, mutexattr, is a pointer to a Property object that defines the property to initialize the lock. If the pointer is null, the default property is used. The properties of the lock are described in detail in the following sections of this article. 3. application, release and attempt to unlock the mutex: Pthread_mutex_lock (), Pthread_mutex_unlock (), Pthread_mutex_trylock () A "function prototype: extern int pthread_mutex_lock (pthread_mutex_t *__mutex);extern int Pthread_mutex_trylock (pthread_mutex_t *__mutex);extern int Pthread_mutex_unlock (pthread_mutex_t *__mutex);B "return: Successful return 0, failure returns an error number to indicate an error. (Pthread_mutex_unlock () errno variable not set) conditional variable communication mechanism:1, the condition variable basic principle: The condition variable's appearance, may compensate the mutual exclusion lock flaw, some problems only by the mutual exclusion lock cannot solve. However, conditional variables cannot be used alone, and mutually exclusive access to the resource must be implemented together with the mutex. Example: an issue in which mutexes cannot be resolved. int i = 3;int j = 7;pthread A pthread_b Pthread_mutex_lock (); pthread_mutex_lock () { {i++; if (i==j) j--; do_something (); } }Pthread_mutex_unlock (); pthread_mutex_unlock (); ——————————————————————————————————————in the previous example: two threads preemption mutexes may cause the do_something () function in Pthread B to never execute. This is what programmers don't want to see. After careful analysis, you can get thread B actually does not need to keep the application release lock, its operation only need a situation. Notifies the B thread to execute do_something () when the a thread satisfies i = = J. Conditional Variables Basic operations:function function Initialize condition variable pthread_cond_init () blocking wait condition variable pthread_cond_wait () notifies the first thread waiting for the condition variable pthread_cond_signal () waits for the condition variable pthread_cond_timedwait () within the specified timedestroy condition variable state Pthread_cond_destroy () 2 . Initialization and destruction of conditional variables: pthread_cond_init (), Pthread_cond_destroy () A "function prototype: extern int pthread_cond_init (pthread_cond_t *__restrict __cond,__const pthread_condattr_t *__restrict __COND_ATTR);extern int Pthread_cond_destroy (pthread_cond_t *__cond); B "return: Successful return 0, failure to return an error number to indicate an error. C "parameter: The first parameter points to a pointer to the condition variable to initialize or corrupt, and the type of the condition variable is pthread_cond_t. The second argument points to a pointer to the conditional Property object. The Property object defines the attribute of the condition variable to initialize, or the default if this variable is initialized to null. For the condition attribute, this article will be described in detail later. 3, notify the thread waiting for the condition variable: pthread_cond_signal (), Pthread_cond_broadcast () A "function prototype: extern int pthread_cond_signal(pthread_cond_t *__cond); extern int Pthread_cond_broadcast(pthread_cond_t *__cond); B "Description:The A, pthread_cond_signal () function is used to wake the first thread waiting for a condition that is associated with the condition variable cond. This function does not work if no threads are blocked on the cond. If cond blocks multiple threads, the scheduling policy determines which thread to unblock. Obviously, in this function, the amount of semaphores that the current thread consumes is implicitly released (note: The signal and semaphore are not a thing, and the signal and semaphore are detailed in process and process communication). the B, Pthread_cond_broadcast () function is used to wake up all threads waiting for the condition associated with the condition variable cond. This function does not work if no threads are blocked on the cond. 4. wait condition variable: pthread_cond_wait (), pthread_cond_timedwait () A "function prototype: extern int pthread_cond_wait (pthread_cond_t *__restrict __cond,pthread_mutex_t *__restrict __mutex);extern int pthread_cond_timedwait ( pthread_cond_t *__restrict __cond,pthread_mutex_t *__restrict __mutex, c6>__const struct Timespec *__restrict __abstime); B "parameter description: Cond is a pointer to the condition variable to wait for, and the mutex points to a pointer to the mutex associated with the condition variable cond. the implementation of the Pthread_cond_wait () and pthread_cond_timedwait () functions is a process of unlocking and locking the mutex first . Pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) function passed in the parameter mutex is used to protect the condition, because when we call pthread_cond_wait, If the condition does not hold, we enter the block, but when the condition variable changes, we miss the condition. Because this thread has not yet been placed on the waiting queue, the mutex must be locked before calling Pthread_cond_wait, that is, calling Pthread_mutex_lock (), pthread_cond_wait after putting the thread in the blocking queue, The mutex is automatically unlocked, allowing other threads to acquire the right to lock. This allows other threads to access the critical resource and wake up the blocking process at the appropriate time. When Pthread_cond_wait returns, it automatically locks the mutex. Thread A: Sends a signal when the condition is met. Thread B: Locks a mutex first to allow mutually exclusive access to the value of count. Waits for the COUNT value to reach Max_count in a while loop. Because when a condition is met, multiple threads may be awakened. So it is necessary to determine whether the condition is satisfied. Pthread_cond_wait first puts the calling thread into the wait queue for the condition variable, and then releases the mutex. When the function returns, the mutex is added to the lock. Finally, unlock the mutex and let the other threads use the Count variable. (Add a write lock waiting is to occupy manger not to poop, there is data update this operation domain and do not write operation, can only unlock the first ~ ~ ~ ~) pthread_cond_timedwait () has one more parameter, that is, Abstime,abstime is the number of seconds since January 1, 1970 00:00:00, which is an absolute time. Wait for the time, then do not block, go down to execute the program. The TIMESPEC structure declares as follows:struct Timespec {long tv_sec;long tv_nsec;};C "return: If successful, return 0, Failure returns an error number. read/write lock communication mechanism:1, the basic principle of reading and writing : In the data read and write operations, is often read accounted for the main part. To satisfy the requirement that multiple reads are currently allowed, but only one write is allowed. The thread provides a read-write lock to implement. The basic principles of read and write locks are:a "If there are other threads reading the data, allow other threads to perform read operations, but write operations are not allowed." B "If another thread has requested a write lock, the other thread cannot request a read lock, nor can it request a write lockread-write lock basic operation functions are as follows: function function Initialize read-write lock pthread_rwlock_init () blocking Request read lock pthread_rwlock_rdlock () non-blocking request read lock pthread_rwlock_tryrdlock () block Request write lock pthread_rwlock_wrlock () non-blocking request write lock pthread_rwlock_trywrlock () release Lock (read lock and write lock) pthread_rwlock_unlock () Destroy read/write lock Pthread_rwlock_destroy () 2. initialization/destruction of read/write Locks: pthread_rwlock_init (), Pthread_rwlock_destroy () A "function prototype: extern int pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,__const pthread_rwlockattr_t *__res Trict __attr);extern int Pthread_rwlock_destroy (pthread_rwlock_t *__rwlock);B "returns: returns 0 if successful, otherwise returns an error number to indicate an error. C "parameter description: The first parameter points to a pointer to the read-write lock to initialize. The type is pthread_rwlock_t. The second parameter is a property of a read-write lock. This is explained in detail later in this article. 3. apply for read lock, write lock and unlock read/write Lock: Pthread_rwlock_rdlock (), Pthread_rwlock_tryrdlock (), Pthread_rwlock_wrlock (), Pthread_ Rwlock_trywrlock (), Pthread_rwlock_unlock () A "function prototype: extern int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock);extern int Pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock); extern int Pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock); extern int Pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock); extern int Pthread_rwlock_unlock (pthread_rwlock_t *__rwlock); B "Description: Successful return 0, failure returns an error number to indicate an error. when calling Pthread_rwlock_unlock, be aware that:A, if this function is called to release the read lock on the read-write lock Rwlock, but there are currently other read locks on this read-write lock, the read lock will maintain the thread read lock state. It's just that the current thread is not one of its people. B, if this function releases the last read lock of a read-write lock, the object will be in an unlocked state without an owner. C, if this function is called to release a write lock for a read-write lock, the read-write lock will be unlocked without the owner. Thread signal:threads are a lightweight process, so the signal for a process also applies to threads. However, relative to the process signal, the thread has the private data associated with the signal-the thread signal mask, which determines that the thread has the following characteristics in the signal operation:a "Each thread can send a signal to the other thread first, and the Pthread_kill () function is used to do this. B "Each thread can set its own blocking collection. Pthread_sigmask () is used to complete this operation. Similar to the Sigprocmask () function in the process. The thread created by the main process inherits the mask of the main process. C "Each thread needs to set up a processing method for a signal, but there can be only one effective way to handle a signal in the same process, that is, how the last set is handled. That is, in all threads, the same signal is thread to the same signal at any line.D "If another process sends a signal to the current process, it is unknown which one is formed to deal with it." 1. send a signal to the specified thread: Pthread_kill () A "function prototype: extern int Pthread_kill (pthread_t __threadid,int __signo)B "parameter description: ThreadID is the target thread, and is a thread within the same process , Sigo is the signal to send. The Pthread_kill () function is used to request that the signal be routed to the thread, and the signal will be directed asynchronously to the thread during the call process. If the Signo is 0, an error check is performed without sending a signal. After successful completion, Pthread_kill () will return 0. Otherwise, an error number is returned to indicate the error (the errno variable is not set). the Help document for this function: http://www.man7.org/linux/man-pages/man3/pthread_kill.3.html2. Signal Mask of the calling thread: Pthread_sigmask () A "function prototype: extern int pthread_sigmask (int __how,__const __sigset_t *restrict __newmask,__sigset_t *restrict __oldmask); B "Description: The function is similar to the Sigprocmask () function in the process signal. Pthread_sigmask () A signal mask that is used to check or to reroute a thread. (This section can refer to the process and process communication signals section). C "parameter: The first parameter how defines how to change the signal mask of the calling thread. Its legal value has the following three (this dot content with Sigprocmask () repeats)#define Sig_block 0 #define Sig_unblock 1#define SIG_SETMASK 2 Macro Description:Sig_block: Adds the collection described by the 2nd parameter to the current process's blocked signal set. Sig_unblock: Removes the collection described by the 2nd parameter from the current process blocking signal set. Sig_setmask: Regardless of the previous blocking signal, only sets the current process block set to the 2nd parameter described by the object. if the Newmask value is a null pointer, the parameter how does not make sense and does not have a more blocked signal set for the thread, so the call can be used to query the currently blocked signal. D "return: After successful execution, return 0, failure to return an error number to indicate an error (errno variable not set), and if for some reason Pthread_sigmask () fails, then the signal mask of the thread will not change. PostScriptThe properties of the mutex mentioned above, the properties of the condition variable and the properties of the read-write lock are three blocks of content, organized in the next article. In the thread and thread communication directory, please pay attention.

Linux Advanced Programming Fundamentals Series: Inter-thread communication

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.