Thread synchronization mechanism acquaintance [Reserved]

Reasons for thread synchronization: resolve data access conflicts .

(A), superficial understanding thread synchronization: The main thread synchronization in order to complete data sharing and synchronization between threads, maintaining data integrity. (Such as in multiple threads, some sensitive data portion to allow access to a plurality of threads simultaneously, this time on the use of synchronous access technology to ensure data at any time, at most one thread has access, to ensure the integrity of data .PS: in multi-threaded programming, the most troublesome is that data sharing. because you do not know which thread will be the time at which it operates, you can not know that thread to run, after which thread will run through the following techniques reasonable arrangements for the competition for resources between threads :)

(II) to address the main technical thread synchronization:

         1, using mutex

         2, the use of semaphores

         3, variable conditions of use

Introduction (c) related technologies

    1, when a mutex? ? ? ?

Some variables in a certain time or resources to process only one thread at a time of the visit of its practical mutex must be controlled. For example there is a global list (see the following code), there are several working threads, each header node removed from the linked list, and then processing the head node. Thread 1 is now removed such as head node, his operation is as follows (so-called key code)

Item * p = queue_list; (take the list of the first node)

queue_list=queue_list->next;

Process_job(p);

Free(p);

When the thread is finished with the first step 1, which is Item * p = queue_list, this time the system stops running thread 1, and instead running thread 2. Thread head node 2 still removed, then processed, and finally releases the node. After a period of time, thread 1 retrieve operation. And this time, in fact, pointed to by p node has been freed thread 2, and thread 1 to have no awareness. He would then run process_job (p). This will lead to unpredictable consequences! In this case, it must be controlled by the mutex.

2, mutex implementation detail:

    (1), first declare a variable of type pthread_mutex_t my_mutex PTHREAD_MUTEX_INITIALIZER;

     (2) using pthread_mutex_lock (& ​​my_mutex) before the key code; mutex to be locked.

     (3) Key Code

     (4) to unlock the mutex use pthread_mutex_unlock (& ​​my_mutex) when the key code completion.

2. Why use condition variables? ? ? ?

    Consider the following situation: If a thread is waiting for a signal that if the signal is set, the thread continues, otherwise stop to inquire whether the signal is set, knowing that a signal is detected only after the execution was set down. This will waste a lot of resources, so in this case you need to use condition variables for processing. By condition variables, we can wait for a thread blocking signal until the signal when it wake up again.

3, condition variable implementation details:

    (1), first declare a variable of type pthread_cond_t, then initialized. The pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;

   (2), if the signal is set (for example, on a global list of operating time, adding a node when) you call pthread_cond_signal (& my_cond) (the function parameter is a condition variable function is to awaken a thread) function to send a signal If at this time there is a thread is waiting for the signal, then the thread will be awakened, if not, the signal will be ignored. If the signal when there is time to wake up all the threads on the use of function: pthread_cond_broadcast (); to achieve.

   (3)、在对线程在对信号进行处理的时候(比如在处理链表的时候,如果链表不是空的,则进行处理。如果链表是空的则就调用wait函数来进行阻塞线程),如果有相应的信号就直接执行下去,如果没有信号发生则调用pthread_cond_wait(&my_cond,&my_mutex)等待信号(该函数的第一个参数是条件变量,第二个参数是一个mutex。在调用该函数之前必须先获得互斥量。如果线程阻塞,互斥量将立刻会被释放。)

细节:在使用条件变量对两个或多个线程进行同步的时候,在pthread_cond_wait之前要对互斥量进行加锁,当程序执行到pthread_cond_wait()的时候将要执行以下原子操作:

1)对互斥量解锁。

2)挂起线程,等待条件变量满足,被唤醒。

3)在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。

    这样就可以解释为什么在 pthread_cond_signal 之前对互斥变量加锁时,能够获取到锁,而不产生死锁。

(三)条件变量与互斥锁、信号量的区别

       1.互斥锁必须总是由给它上锁的线程解锁,信号量的挂出即不必由执行过它的等待操作的同一进程执行。一个线程可以等待某个给定信号灯,而另一个线程可以挂出该信号灯。

       2.互斥锁要么锁住,要么被解开(二值状态,类型二值信号量)。

       3.由于信号量有一个与之关联的状态(它的计数值),信号量挂出操作总是被记住。然而当向一个条件变量发送信号时,如果没有线程等待在该条件变量上,那么该信号将丢失。

       4.互斥锁是为了上锁而设计的,条件变量是为了等待而设计的,信号灯即可用于上锁,也可用于等待,因而可能导致更多的开销和更高的复杂性。

PS:关于信号量方面的知识暂时还没有研究,在这里就不谈了。


Guess you like

Origin www.cnblogs.com/xjyxp/p/11270358.html