WEBVTT

00:04.920 --> 00:08.280
So guys, now let us try to understand the condition variables.

00:08.490 --> 00:15.600
So condition variables allow us to have finer control over taking the decision on when and which competing

00:15.630 --> 00:17.980
thread to block or resume.

00:18.000 --> 00:24.090
Now, competing threads are the set of threads which are competing to get an access to a shared resource

00:24.090 --> 00:25.020
of a program.

00:25.020 --> 00:25.680
Right.

00:25.710 --> 00:28.950
We call those set of threads as competing threads.

00:29.070 --> 00:35.850
So condition variables give a finer control over taking the decision on when and which competing thread

00:35.850 --> 00:37.400
to block and resume.

00:37.410 --> 00:38.140
Right.

00:38.160 --> 00:41.070
So don't worry, maybe this definition do not make much sense.

00:41.070 --> 00:45.770
As of now, we will go into discuss plenty of examples on condition variables.

00:45.840 --> 00:49.290
Let us try to discuss condition variables with the help of an example.

00:49.650 --> 00:55.260
So, for example, let us suppose that you have a thread T1 in your program and the thread T1 during

00:55.260 --> 00:59.670
the course of its execution finds a queue empty.

00:59.700 --> 01:05.530
Now this queue is any queue or any data structure which is being maintained by a program, and this

01:05.530 --> 01:07.480
queue has some data elements in it.

01:07.480 --> 01:08.050
Right.

01:08.080 --> 01:09.610
What those data elements are.

01:09.640 --> 01:12.370
It is not important for this discussion here.

01:12.370 --> 01:17.860
The thread T1 is a consumer thread which wants to just consume one element from this queue.

01:17.890 --> 01:18.400
Here.

01:18.400 --> 01:23.500
Consuming the element means removing the element from this queue and then process that element.

01:23.500 --> 01:24.190
Right?

01:24.190 --> 01:29.620
So here thread T1 is a consumer thread which is trying to consume this particular queue.

01:29.650 --> 01:30.390
Right?

01:30.400 --> 01:33.160
So the thread t1 finds the queue empty.

01:33.190 --> 01:38.590
It means that the thread t1 really do not have anything to consume from the queue.

01:38.620 --> 01:39.360
Right.

01:39.370 --> 01:47.080
So it means that our thread T1 wants to wait until some other thread of the process put an element in

01:47.080 --> 01:47.830
the queue.

01:47.950 --> 01:48.760
Right.

01:48.940 --> 01:56.680
So the thing to be noted here is that that the thread T1 chooses to block itself based on the condition

01:56.680 --> 01:58.330
that the queue is empty.

01:58.330 --> 01:59.170
Right?

01:59.290 --> 02:05.680
It would not have blocked itself if there was an element in the queue, but since the queue is empty,

02:05.680 --> 02:13.660
therefore thread T1 has nothing to consume and therefore thread T1 decides to wait itself or block itself

02:13.660 --> 02:18.390
until some other thread of the process places an element in the queue.

02:18.400 --> 02:19.210
Right.

02:19.330 --> 02:26.260
Once the element is placed in the queue, our thread which is in the blocked state now will be resumed

02:26.260 --> 02:28.980
and it will consume the element from the queue.

02:28.990 --> 02:29.850
Right.

02:29.860 --> 02:31.840
So this is one example.

02:32.720 --> 02:40.390
So condition variable allows threat to get itself blocked or wake up when certain condition is met.

02:40.400 --> 02:41.140
Right.

02:41.150 --> 02:43.730
And this is what we discussed in this example.

02:43.730 --> 02:44.480
Right?

02:44.660 --> 02:51.440
So you can see that condition variables allows the threat to get blocked or wake up when certain conditions

02:51.440 --> 02:52.280
are met.

02:52.280 --> 02:53.000
Right.

02:53.000 --> 02:58.490
So now you must be thinking that, okay, we have a condition variable which serves this purpose, then

02:58.490 --> 03:00.770
why we had mutex in the first place.

03:00.800 --> 03:03.710
How condition variables are different from indexes.

03:03.740 --> 03:07.670
Can you write a paragraph or a short note on this at this point of time?

03:10.390 --> 03:12.010
Please think about it.

03:12.250 --> 03:15.520
So mutex is only says that go ahead.

03:15.520 --> 03:21.910
If you have an access over the shared resource and if that particular shared resource is already blocked

03:22.090 --> 03:27.260
or locked by some other thread, then the current thread has no choice but to wait.

03:27.280 --> 03:28.030
Right.

03:28.030 --> 03:33.100
So mutex is like saying either you have an access or you don't have an access.

03:33.100 --> 03:33.850
Right.

03:33.880 --> 03:39.850
Consider an example on the right hand side where the red box represents the critical section which is

03:39.850 --> 03:43.180
being executed by the thread T1 right now.

03:43.180 --> 03:48.190
Since the thread T1 is already executing in this critical section, it simply means that the thread

03:48.220 --> 03:57.580
T1 has successfully gained a lock on the mutex m and this mutex M is associated with this critical section,

03:57.580 --> 03:58.340
right?

03:58.360 --> 04:04.510
So thread T1 has successfully gained a lock on this mirax and therefore the rest of the threads of the

04:04.510 --> 04:12.290
process that is thread t2, t3, T4 and T5 are simply blocked and prevented from entering the critical

04:12.290 --> 04:13.010
section.

04:13.010 --> 04:13.670
Right.

04:13.700 --> 04:20.210
Now here, one thing to be noted here is that that the condition on which the thread T2, T3, T4 and

04:20.210 --> 04:28.310
T5 have decided to wait and block themselves is that that the mutex which they are trying to lock is

04:28.310 --> 04:29.540
already locked by the thread.

04:29.570 --> 04:30.830
T1 Right.

04:30.860 --> 04:32.390
There is no other condition.

04:32.390 --> 04:38.090
There is only one condition that the mutex which these threads are trying to lock is already locked

04:38.090 --> 04:39.500
by some other thread.

04:39.740 --> 04:46.310
So this is what here mutex says that if the mutex is already locked then the thread which is trying

04:46.310 --> 04:48.860
to lock the mutex again would get blocked.

04:49.590 --> 04:55.560
So in this diagram, when the threat t one leaves the critical section, the lock is granted to the

04:55.560 --> 04:56.580
blocked threat.

04:56.610 --> 05:05.160
That is one of the threads among threat T2, T3, T4 and T5 and that thread would be chosen by the kernel

05:05.160 --> 05:06.300
scheduling policy.

05:06.330 --> 05:11.930
Here, programmer has little control as to which thread would go next into the critical section.

05:11.940 --> 05:14.120
So why do we need condition variables?

05:14.130 --> 05:20.310
Let us see that, in which scenarios the mutexes will fail and you really cannot implement the logic

05:20.310 --> 05:21.690
using Mutexes alone.

05:22.200 --> 05:25.140
So using mutexes we can't implement the below logic.

05:25.140 --> 05:32.430
That is, if the thread finds some queue empty, then the thread chooses to wait until the queue has

05:32.430 --> 05:33.690
some element in it.

05:33.720 --> 05:40.320
Right now in this example, if the thread finds the queue empty, the thread chooses to block itself.

05:40.320 --> 05:41.040
Right.

05:41.040 --> 05:47.370
So here we have a customized condition and that customized condition is that that the queue is empty.

05:47.370 --> 05:48.060
Right?

05:48.060 --> 05:52.180
If the queue is empty, the thread decides to block itself.

05:52.540 --> 05:58.450
So using mutexes we cannot implement this logic that is condition based blocking.

05:58.450 --> 05:59.170
Right.

05:59.170 --> 06:02.740
And we need condition variables for this.

06:02.920 --> 06:08.740
So note the term here condition based locking and that is why the condition variable is so named the

06:08.740 --> 06:10.030
condition variable.

06:10.030 --> 06:10.600
Right?

06:10.600 --> 06:17.500
That is block on certain conditions here you don't see any such customized or user defined condition.

06:17.500 --> 06:23.140
The only condition is that that the that the mutex which the thread trying to lock is already locked.

06:23.170 --> 06:28.870
There is no scope of defining user defined condition and taking a decision whether to block the threads

06:28.870 --> 06:29.710
or not.

06:30.370 --> 06:36.190
So now do not think that condition variable is a superset of mutex or condition.

06:36.190 --> 06:42.550
Variable replaces the murex no condition variable plus Murex combo is what it all takes to implement

06:42.550 --> 06:48.250
any advanced thread synchronization scheme, so you can assume that condition variable and mutexes are

06:48.250 --> 06:50.370
like Romeo and Juliet.

06:50.370 --> 06:56.280
Both are required to implement advanced thread synchronization techniques such as monitors or standard

06:56.280 --> 07:02.220
problems such as producer, consumer problem dining, philosophers problem or implementing complex libraries

07:02.220 --> 07:05.010
which could schedule the threads of the process.

07:05.010 --> 07:10.590
Implementing other thread synchronization data structures such as semaphores, wait, queues, barriers,

07:10.590 --> 07:11.400
etcetera.

07:11.430 --> 07:12.150
Right.

07:12.150 --> 07:14.940
You need to use condition variables and mutex both.

07:14.940 --> 07:18.780
In fact, you cannot use condition variable without mutex.

07:18.780 --> 07:25.140
So we will going to discuss how to use condition variables and mutexes together as we progress towards

07:25.140 --> 07:28.050
implementing advanced thread synchronization programs.
