Hello and welcome.
In this video session, we will see the concept of unnamed semaphores.
In the previous video session we had seen the named semaphores.
So basically a named semaphore is a semaphore in which it is present on the file system.
Whereas an unnamed semaphore is one which is present on the memory.
So when we say it is present on the memory, it is similar to the variable and it can be present on
different memory segments.
So an unnamed semaphore can be used within the process and can be.
Used to synchronize between different threads.
In this case, the unnamed semaphore should be kept in the place where it is accessible to all the threads.
That is nothing but a global memory area.
So similarly, unnamed semaphore can be used to synchronize between different threads of different processes.
So in this case, the unnamed semaphore should be placed in a in a memory where the memory is accessible
to both the process.
So in this case, the shared memory is the place where two different processes can access the memory.
We will discuss on the shared memory in next video session, but for now we can think of shared memory
as a.
Part of a or a segment of a memory which can be mapped or accessed across different processes.
Hence, the unnamed semaphore is a memory based semaphore and it does not have any name.
In an unnamed semaphore.
It has the same operations as named Semaphore like Sam.
Wait.
Sam Post.
Sam get value.
But an unnamed semaphore can be created using sam init and is destroyed using sam destroy.
So sam init and Sam destroyed are used only for unnamed semaphores and should not be used for named
semaphore.
Similarly, sam wait is used to get the semaphore.
So when Sam wait is successful it decrements the value of the semaphore.
When Sam Post is successful, it increments the value of the semaphore and Sam get value, gets the
current value of the semaphore.
So these operations are similar for named as well as unnamed semaphore.
Now let's see.
What exactly is Sam Minute?
So this is the prototype of lemonade.
So a lemonade is used to create a semaphore, and it takes the parameter of type pointer to a.
Variable of type seven T and we have a int P.
We'll see what exactly is a P shade?
And this is nothing but the initial value with which it is created.
So if it is successful, it returns a zero or if it is failed, then it returns a minus one.
So in the previous we had told that an unnamed semaphore can be used within the process to synchronize
between the different threads.
So in this case, we have to pass a zero to P shared.
And if we are creating an unnamed semaphore to synchronize different threads that are running in different
process, then we need to specify P shared as one.
So this is the place where p p shared comes into picture.
So when p shade is zero, then the semaphore is to be shared between the threads of calling process
and if p shared is nonzero then the semaphore is to be shared between the process.
And Sam Destroy is used to destroy the unnamed semaphore.
So now, in next, we will see some examples of unnamed semaphore.
Now we will see the example of unnamed semaphore.
So in this program we have included the required header files and.
Here we have a global variable called as Globe, and its initial value is zero and we have created a
variable of type underscore.
So is basically a semaphore variable.
Now we have created a thread function called threadfunc, and the basic intention of thread function
is to increment the global variable globe ten, ten, 10,000 times.
So here basically before incrementing the variable global variable.
So we put a semaphore, we wait for a semaphore and we once the semaphore is obtained, then execute
the critical section.
So this is the critical section in this case that is nothing but the incrementing the global variable.
And once the.
Global variable is incremented.
The same post is called to Give back the semaphore that is obtained.
And now let's see the main function.
So the main function begins with creating three threads T1, T2 and T3 and we are creating a thread
T1 and calling Threadfunc and creating T2 and calling Threadfunc and finally creating third thread T3
and calling Threadfunc.
And to each of the thread functions we are passing the argument thread one thread two and three three.
So now, once three threads are created, we are creating a unnamed semaphore.
So here seminary is used to create an unnamed semaphore and we have to pass the address of the semaphore
variable.
And in this case we are using zero.
Zero implies we are using the synchronization.
Synchronization of threads within the process and value.
One here implies that the initial value of the semaphore is one, and if there is a minus one on on
if init calls minus one then we have an error creating the semaphore and we exit.
So finally, if the init is successful we wait for all the three threads by joining p thread join of
t1, t2 and T3.
So this makes sure that the main function waits for all the three threads to terminate.
Then only the main function destroys the unnamed semaphore.
So now in this case we have one code segment that is shared by three threads that is nothing but T1,
T2 and T3.
Now in this case the.
The expectation would be we have initially the global variable will be zero.
Then each thread increments the global variable for 10,000 times before incrementing.
It takes the semaphore and increments the count to 10,000 and then gives back the semaphore.
So the thread which.
Runs.
Takes the semaphore and then increments the global value.
Global variable and use the semaphore.
So at the end of all the three threads, the value of the global variable would be 10,000 into three.
That is nothing but 30,000.
So let's compile this program.
So here we can see that there there is a thread synchronization that needs to be.
They can get.
So for this purpose, we are using an unnamed semaphore.
So now let's compile this program.
So here we are compiling the program GCC one, underscore the name of the program and linking using.
LP thread and the output file we are creating is unnamed, so let's compile this.
So now we have created a object file.
Output file as unnamed.
So now let's run the program.
So after running, we can see that by the end of the program, the global variable value, the value
of the global variable is 30,000.
So here, using an unnamed semaphore, we are able to synchronize between the three running threads.
So here the thread one was running and it avoided the semaphore.
So when it unveiled the semaphore, the semaphore count, which was created by one, was now zero.
So the same weight, the thread one called same weight and the value of semaphore is zero since the
value of semaphore is zero, the other thread which are running is not able to get the semaphore and
hence they are not able to execute the critical section.
So now thread two.
Once the thread one finished executing it gave the semaphore by executing some post and as a result
the thread two got the semaphore and it executed the critical section and.
And now the thread too has given the semaphore and hence as a result, the thread three which is running,
is a wild semaphore and it executed the critical section.
So now there is a sequence of execution so that any thread which gets the semaphore, it executes until.
It finishes the critical section and then it gives the semaphore or it increments the semaphore so that
the other thread can get the semaphore and enter the critical section.
So in this case, when any thread gets the semaphore and enters the critical section so no other thread
can enter the critical section until the thread which has got the.
Semafor has released the Semafor.
So now let's see an simple example.
So in this program, let's do some changes and see.
So now here we have created a semaphore with initial value equal to one.
So now let's say if I create a.
Unnamed semaphore with initial value equal to in this case, can we guess the output of this program?
Let's compile this.
Now let's run the program.
So when I run this program, the expected result will not be 30,000.
That is, the global variable will not be 30,000.
Let's.
Run it to understand.
So we can see that every time we run the program, it gives different result.
So sometimes it can be 30,000 as well, but the value is not consistent.
So every run we are getting a different value.
So here we got 30,000, but in this case we got 27417.
So next run we got two, five, six, seven three.
So the explanation to this output will be as follows.
So in this case, we have one critical section.
And so in this case, when we have one critical section and we have created a semaphore by count equal
to two.
So what happens is any two threads can simultaneously enter the critical section, hence the global
value will be altered or it it gives an unexpected result.
So since we have one critical section here and we want only one thread to enter the critical section,
so we should have a semaphore with count equal to one, then we will not have a synchronization issues.
So let's.
Change this back to one.
And now let's compile the program once again.
Now let's run the program.
So now the any number of time we run the program, we get the same result.
That is 30,000.
So.
Now we are able to achieve the synchronization between threads within the process.
Hence.
We are using an unnamed semaphore.
So by using an unnamed semaphore, there is no entry in the file system.
That means we are not creating any semaphore by a name and it does not have an entry in the file system.