WEBVTT

00:06.270 --> 00:11.910
So guys, now we will going to implement the last part of our solution and we will going to implement

00:11.910 --> 00:15.840
this API philosopher, get access, both spoons, right?

00:15.840 --> 00:22.380
So the implementation of this API has to abide by this following logic represented by this flowchart,

00:22.590 --> 00:27.930
we will going to provide the implementation of this API exactly as per this flowchart.

00:27.930 --> 00:28.650
Right.

00:29.890 --> 00:36.250
And you can see this flow chart has been designed by keeping the constraints in mind which our problem

00:36.250 --> 00:38.410
statement has presented to us.

00:38.680 --> 00:45.460
You can see that to start with, our philosopher will try to grab an axis on the left spoon.

00:45.490 --> 00:50.750
So the very first thing that we will do is that we will check whether the left spoon is available.

00:50.770 --> 00:55.990
If the left spoon is not available, then our philosopher thread must wait on the condition variable

00:55.990 --> 00:57.150
of the left spoon.

00:57.160 --> 00:57.970
Right.

00:58.330 --> 01:04.330
And in case if the left spoon is available, then our philosopher thread will update the state of the

01:04.330 --> 01:11.530
spoon in a way which reflects that the left spoon is now allocated to the philosopher right, and it

01:11.530 --> 01:16.510
is after the left spoon has been successfully granted to the philosopher.

01:16.630 --> 01:20.770
Our philosopher will now check if the right spoon is available or not.

01:20.860 --> 01:27.640
And as per the problem statement, if the right spoon is not available, our philosopher who has successfully

01:27.640 --> 01:34.710
gained an access on the left spoon, will roll back and give up the access on the left spoon as well.

01:34.730 --> 01:35.540
Right.

01:35.870 --> 01:41.690
And in case if the right spoon is available, then our philosopher will end up with an access to both

01:41.690 --> 01:42.620
the spoons.

01:42.620 --> 01:44.240
And this function must return.

01:44.240 --> 01:44.660
True.

01:44.660 --> 01:50.810
Which indicates that the philosopher has been successfully granted an access to both of his spoons.

01:50.810 --> 01:51.560
Right.

01:52.700 --> 01:55.700
So this flowchart is pretty much simple and straightforward.

01:55.700 --> 02:02.300
And this flowchart exactly depicts the problem statement as well as the constraints that we have imposed

02:02.300 --> 02:03.590
on our problem.

02:03.890 --> 02:08.420
So let us start with the implementation of this flowchart in the function philosopher.

02:08.450 --> 02:10.190
Get access both spoons.

02:10.370 --> 02:11.210
Right.

02:11.240 --> 02:16.850
This function returns true or false depending on whether the philosopher has been granted access to

02:16.850 --> 02:19.520
both of his spoons successfully or not.

02:21.310 --> 02:27.280
So guys, to start with, the very first thing that we need to do is to check whether the left spoon

02:27.280 --> 02:28.790
is available or not.

02:28.810 --> 02:29.540
Right.

02:29.560 --> 02:33.580
If it is available, then we will grab an access to the spoon.

02:33.580 --> 02:38.020
If it is not available, then our philosopher thread must wait on the condition variable.

02:38.050 --> 02:40.300
So let us implement this logic.

02:42.660 --> 02:47.040
So to start with, I already have a pointer to the left spoon of the philosopher.

02:47.040 --> 02:54.780
So what I will going to do is that I will lock the mutex of the left spoon, right, because I'm going

02:54.780 --> 02:58.980
to inspect the state of the left spoon whether the spoon is available or not.

02:59.970 --> 03:06.690
The thread must lock the mutex of the spoon so that at the time when the thread is checking or inspecting

03:06.690 --> 03:11.730
the state of the resource, the state of the resource must not be changed by any other philosopher in

03:11.730 --> 03:12.570
the program.

03:12.580 --> 03:13.320
Right?

03:14.730 --> 03:21.720
So once I have successfully gained a lock on the mutex of the left, spoon or philosopher thread can

03:21.720 --> 03:26.100
now deploy a predicate check on using while condition.

03:26.100 --> 03:26.820
Right.

03:26.850 --> 03:33.180
This is something that we have been doing in a standard way now, not that our philosopher function

03:33.180 --> 03:36.270
is trying to get an access on a resource.

03:36.300 --> 03:41.100
It means that our philosopher function is now behaving as a consumer thread.

03:41.460 --> 03:49.320
So it means that in order to consume a resource, we need to deploy the steps from S1 to S5.

03:49.440 --> 03:50.240
Right?

03:50.250 --> 03:55.770
So these are nothing, but these are the steps number S1, which involves checking of the predicate

03:55.770 --> 03:56.580
condition.

03:56.610 --> 04:00.990
Here I am checking whether the left spoon is available or not.

04:01.000 --> 04:01.720
Right.

04:02.560 --> 04:09.640
So this while condition will become true if the left spoon is already being used by some other philosopher.

04:09.670 --> 04:10.390
Right.

04:10.390 --> 04:16.930
If that is true, then my current philosopher will going to block on the condition variable of the left

04:16.930 --> 04:17.590
spoon.

04:17.800 --> 04:18.580
Right.

04:18.580 --> 04:19.270
So here.

04:19.270 --> 04:26.470
Now, in this case, we will going to implement exactly the steps which a typical consumer thread implements.

04:26.500 --> 04:27.250
Right?

04:27.400 --> 04:35.290
So we will proceed beyond line number 139 only when the left spoon is available to be used by the philosopher.

04:35.290 --> 04:35.980
Right.

04:36.010 --> 04:41.440
This, while condition will become false only when the left spoon becomes available.

04:41.530 --> 04:42.370
Right.

04:42.400 --> 04:48.400
In case if our philosopher thread gets blocked on this condition variable, our philosopher thread would

04:48.400 --> 04:53.110
wake up only when it would receive a signal from other philosopher thread.

04:53.140 --> 04:59.350
In that case, our philosopher thread will again check the predicate condition to decide whether our

04:59.350 --> 05:03.260
philosopher thread can grant an access on the left spoon or not.

05:03.290 --> 05:12.650
So from line number 130 to line number 139, this is a standard predicate check condition which a typical

05:12.650 --> 05:14.630
consumer thread implements.

05:14.900 --> 05:15.680
Right?

05:17.090 --> 05:24.950
So we will be executing beyond line number 139 when the left spoon is available to be used by the philosopher.

05:24.980 --> 05:25.730
Right.

05:25.730 --> 05:32.750
So now the second thing that I need to do is to grab the left spoon, right, because it is available.

05:32.780 --> 05:41.270
So I will update the state of the left spoon such that the left spoon now belongs to our philosopher,

05:41.300 --> 05:42.140
right?

05:43.010 --> 05:49.300
And now that I am done with the left spoon, now it's the time to unlock the mutex of the left spoon.

05:49.310 --> 05:50.090
Right.

05:50.330 --> 05:56.690
So at this point of time in the code, the left spoon has been successfully grabbed by my philosopher.

05:56.960 --> 06:00.700
And now, as per the flowchart, I will come to the right spoon.

06:00.710 --> 06:03.830
I will check whether the right spoon is available or not.

06:04.100 --> 06:11.360
So going further in this function, what I will going to do is that our philosopher will going to check

06:11.360 --> 06:14.590
whether the right spoon is available or not.

06:14.600 --> 06:20.820
So again, my philosopher thread has to lock the mutex of the right spoon before inspecting the state

06:20.820 --> 06:21.930
of the right spoon.

06:22.020 --> 06:22.830
Right.

06:23.040 --> 06:29.580
Always remember that in multithreading or in thread synchronization, whenever your thread has to inspect

06:29.580 --> 06:34.260
the state of the resource, the resource must be locked by a checking thread.

06:34.260 --> 06:35.040
Right.

06:35.550 --> 06:43.110
So now, going forward, my philosopher thread will check whether the right spoon is available or not.

06:43.140 --> 06:50.580
Now if the right spoon is not being used by any other philosopher, it means that is used.

06:50.580 --> 06:52.740
Flag of the right spoon would be false.

06:52.740 --> 06:58.620
So it means that this right spoon is available if this if condition becomes true.

06:58.890 --> 06:59.730
Right.

06:59.730 --> 07:04.620
So in that case my philosopher thread would grab an access on the right spoon.

07:04.830 --> 07:05.580
Right?

07:05.580 --> 07:12.690
So you can see here my philosopher thread is updating the state of the right spoon in a way that it

07:12.690 --> 07:15.810
reflects that the right spoon belongs to my philosopher.

07:15.840 --> 07:16.650
Right?

07:16.650 --> 07:18.330
And we are done here.

07:18.330 --> 07:21.690
So it's time to unlock the mutex of the right spoon.

07:21.690 --> 07:27.690
And at this point of time in the code, both the left and the right spoon has been successfully grabbed

07:27.690 --> 07:29.070
by my philosopher.

07:29.070 --> 07:30.930
So this function should return.

07:30.930 --> 07:32.370
True, right?

07:32.460 --> 07:34.320
We are done in this function.

07:35.490 --> 07:40.230
But what will happen if the right spoon is not available?

07:40.230 --> 07:40.850
Right?

07:40.860 --> 07:43.830
That is, it is being used by some other philosopher.

07:43.830 --> 07:48.120
So as per this flowchart, we will going to implement this box.

07:48.120 --> 07:49.620
That is the last box.

07:49.650 --> 07:52.110
That is give up the left spoon as well.

07:52.110 --> 07:54.380
If the right spoon is not available.

07:54.390 --> 08:03.510
So going further in this code, you can see that I am checking that if the right spoon is being used

08:03.510 --> 08:05.220
by some other philosopher.

08:05.220 --> 08:06.090
Right.

08:06.990 --> 08:13.590
So this elseif condition says that the right spoon is being used and by some other philosopher that

08:13.590 --> 08:15.420
is the owner of this.

08:15.420 --> 08:15.720
Right?

08:15.720 --> 08:18.510
Spoon is not equal to my philosopher.

08:18.510 --> 08:25.320
So I would enter inside the inner if condition, only when the right spoon is being used by some other

08:25.320 --> 08:26.250
philosopher.

08:26.250 --> 08:33.240
So in that case, my philosopher thread has to give up an access on the left spoon as well.

08:33.240 --> 08:39.960
So again, lock the mutex of the left spoon because my philosopher thread has to update the state of

08:39.960 --> 08:45.300
the left spoon so that the left spoon do not belong to my philosopher anymore.

08:45.910 --> 08:46.660
Right.

08:46.660 --> 08:54.190
So you can see that I'm updating the state of the left spoon again and unlock the mutex of the left.

08:54.190 --> 08:54.880
Spoon.

08:55.120 --> 08:55.960
Right.

08:55.960 --> 09:02.950
And since right spoon is not available to my philosopher, so unlock the mutex of the right spoon as

09:02.950 --> 09:04.960
well and return false.

09:04.990 --> 09:06.070
I'm done.

09:06.070 --> 09:11.470
So you can see that this piece of code simply make my philosopher to roll back.

09:11.590 --> 09:12.370
Right?

09:12.370 --> 09:17.620
Because the right spoon was not available and it was being used by some other philosopher.

09:17.650 --> 09:26.350
My current philosopher intentionally loses the access to the left spoon as well and return false from

09:26.350 --> 09:27.190
this function.

09:28.400 --> 09:36.530
And finally, the last case that is we will hit this else block only when the right spoon is being used

09:36.530 --> 09:38.930
by our current philosopher only, Right?

09:38.930 --> 09:42.050
So most probably we will not going to ever hit this else.

09:42.050 --> 09:45.740
Block But there is no harm in this case.

09:45.740 --> 09:48.770
We will simply unlock the mutex of the right spoon.

09:48.770 --> 09:52.700
And the right spoon is already being used by our philosopher.

09:52.700 --> 09:55.880
So simply return true, right?

09:56.770 --> 10:03.240
So most probably we will not going to hit the lines number 191 to line number 194.

10:03.250 --> 10:08.740
But for the sake of completeness of the program covering all the scenarios, let us complete the else

10:08.740 --> 10:09.730
block as well.

10:09.970 --> 10:10.690
Right.

10:11.170 --> 10:18.790
So this completes the implementation of this function and the line number 197 and 98 is actually a dead

10:18.790 --> 10:19.390
code.

10:19.390 --> 10:27.760
We will never going to hit the line number 197, because in every branch of this code we have returned.

10:27.760 --> 10:28.540
Right?

10:28.750 --> 10:34.360
So you can see that the implementation of this function exactly reflects this flowchart.

10:34.390 --> 10:38.200
We have done nothing extra and nothing less, right?

10:40.330 --> 10:45.880
Now, in the next lecture video, we will compile and we will see how to test whether our dining philosophers

10:45.880 --> 10:52.750
problem solution is working fine or not, and how to test whether every philosopher in this problem

10:52.750 --> 10:55.090
is getting an equal treatment.

10:55.120 --> 11:01.270
That is, it should not happen that one philosopher is starving while the rest of the philosophers are

11:01.270 --> 11:02.590
enjoying the cake.
