Understanding of Thread condition variables

Source: Internet
Author: User
Tags mutex

Understanding the condition variables in the thread:

Recently learning the thread, learning this condition variable, it feels difficult to understand ... Read a lot of information, finally a breakthrough, now will be some of the experience to write down:

Have to mention that the condition variable must be involved in the mutex, this specific why, in another article I reprinted to introduce, interested can understand ...

First, a simple introduction to the condition variable, the condition variable is used to inform the shared data state information. You can use a condition variable to inform the queue that it is empty, or not empty. Why should I refer to a conditional variable in a thread? Here's an example: Thread A is used to write data to the shared data-queue, and thread B is used to read the data in the queue. Of course, this place shared data needs to be protected with a mutex. Before thread B reads, it needs to lock the mutex, then determine if the queue is empty, and if it is not empty, read it directly and then return it OK; Then thread B needs to block until thread a writes data to the queue so that the queue is not empty, and if so, the life cycle of thread B makes no sense, he uses his life to block waiting ... Why. Because thread B has locked the mutex until it is judged, the thread A has a lot of data to write to the queue, but if he does not compete for the lock, he will have to wait for thread B to release the lock ... That's the equivalent of B holding the door key in the house waiting for a home. This is tragic ... Isn't it. So, threading introduces the concept of conditional variables ...

First of all, for example, there are two people, A, a, B has two safe, a, a, a safe belongs to a A, a, a safe belongs to B., unexpectedly, these two safes have a key, and a, b two people have only one key ... The safe inside each locked own cell phone. Now there is one thing: a wants to send a text message to B, and B. b want to see a sent to their own text message content ... These two things are inseparable from the mobile phone, so they have to compete for the only key ... Two kinds of results: 1,a grabbed the key, opened a safe, took out the phone to B a text message, and then the key to just not grab the key b,b Open B safe, remove the phone to see a text message; 2, this second kind of result is interesting, suppose B grabbed this key, open B safe, remove cell phone, But did not see the text message, b how to do it. Very sensible, B re-locked the safe, and then gave the key to a, said to a, you first use it, I wait for you ... A open a safe, to B's mobile phone sent a text message, and then gave the key to B, said to B, I am busy, you do not have to wait, you continue ... And then, B opens the safe and takes out the phone and sees the message ....

Very warm second result, haha, in fact, this is the mechanism of the condition variable (I personally understand, welcome expert to make mistake).

Two people are equivalent to two threads, and the only key is a mutex ... The second result of the entire process in pthread_cond_wait (), pthread_cond_signal () in the realization of the performance of the incisively ... This function blocks the thread B that needs to read the queue, but, before blocking, the condition variable operation will unlock the mutex (then thread a waits for thread B to release the lock, so at this point the thread a competes to the lock and writes the data to the queue, and thread A sends a signal to thread B, wakes up thread B, While unlocking this mutex), when thread B is awakened, the mutex is locked again ... Here's a piece of code that can help you better understand the mechanics of conditional variables:
#include "stdio.h"
#include "Stdlib.h"
#include "Error.h"
#include "string.h"
#include "errno.h"
#include "Pthread.h"
#include "time.h"

typedef struct MY_STRUCT_TAG
{
pthread_mutex_t Mutex;
pthread_cond_t cond;
int value;
}my_struct_t;


my_struct_t data = {
Pthread_mutex_initializer, Pthread_cond_initializer, 0};

int hibernation = 1;


void *wait_thread (void *arg)
{
int status;
Sleep (hibernation);//deliberately want to achieve the second result, that is, let main grab this lock

Status = Pthread_mutex_lock (&data.mutex);//Lock the mutex,
if (status)
{
fprintf (stderr, "Lock Mutex error:%s\n", Strerror (errno));
Pthread_exit (NULL);
}


Data.value = 1;//This operation is the task that this thread needs to complete

Status = Pthread_cond_signal (&data.cond);//After completing the task, wake up the thread waiting for the COND condition variable, note that this function can only wake up one thread at a time (if multiple threads are waiting, they will follow Priority thread ordering ' If you need to wake multiple threads at the same time, you need to use the Pthread_cond_broadcast () function.
if (status)
{
fprintf (stderr, "Signal Error:%s\n", Strerror (errno));
Pthread_exit (NULL);
}


Status = Pthread_mutex_unlock (&data.mutex);
if (status)
{
fprintf (stderr, "Unlock Mutex error:%s\n", Strerror (errno));
Pthread_exit (NULL);
}

return NULL;
}



int main (int argc, char *argv[])
{
int status;
pthread_t wait_thread_id;
struct TIMESPEC timeout;

if (argc > 1)
{
hibernation = Atoi (argv[1]);//default value is 1, you can enter parameter to modify default value
}


Status = Pthread_create (&wait_thread_id, NULL, wait_thread, NULL);//Create Wait_thread thread
if (status)
{
fprintf (stderr, "Create thread Error:%s\n", Strerror (errno));
return-1;
}


Timeout.tv_sec = Time (NULL) + 2;
timeout.tv_nsec = 0;


Status = Pthread_mutex_lock (&data.mutex);
if (status)
{
fprintf (stderr, "Main thread_mutex_lock Error:%s\n", Strerror (errno));
return-1;
}

while (Data.value = = 0)
{
Status = Pthread_cond_timedwait (&data.cond, &data.mutex, &timeout);//This is the time to wait for the function to wait within this time; Pthread_cond_ Wait () does not require waiting time, this function unlocks the mutex first, then blocks, waits for the thread to Wait_thread to send a signal to wake him up. After awakening, this thread will re-lock the mutex. Another problem here is that if wait for the conditional variable is awakened, he needs to lock the mutex for the first time, but the thread that sends the signal does not release the mutex. This wake-up wait needs to wait again, so that it switches the environment two times. So try to ensure that the corresponding mutex is unlocked when the signal is signaled.
if (status = = Etimedout)
{
printf ("Condition wait timed out.\n");
Break
}
else if (status! = 0)
{
fprintf (stderr, "Wait on condition Error:%s\n", Strerror (errno));
Exit (1);
}
}


if (Data.value! = 0)//If the value changes, it means that the thread has modified value and sent a signal to wake up the thread waiting for the COND condition variable.
{
printf ("Conditon was signaled.\n");
}
Status = Pthread_mutex_unlock (&data.mutex);
if (Status! = 0)
{
fprintf (stderr, "Pthread_mutex_unlock Error:%s\n", Strerror (errno));
Exit (1);
}

return 0;
}


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.