Process Synchronisation using semaphores - process

Here is the problem.
I want two processes to occur alternatively, the complete problem is here.
Q. In a system ther are two processes named A and B.When the system starts,the process A executes twice then process B executes once.The Process B cannot execute until process A has executed twice. Once Process A haas executed it can not execute again until process B has executed. The restriction mentioned above allows the process A and B to execute in the following manner.
AABAABAAB...
Write the pseudocode for Process A and B using counting semaphore to achieve the desired synchronisation.
Here is my attemp for this.
Solution:
Process A
var a=1,b=0,i;
begin
repeat
wait(a);
for(i=0;i<2;i++)
printf("A"); // conidering this is what process a does.
signal(b);
forever
end
Process B
begin
repeat
wait(b);
printf("B"); //considering this is what process B does.
signal(a);
forever
end
Is this correct?

An alternative solution would be:
Semaphore as = 1;
Semaphore bs = 0;
A() {
int counter = 0;
while(TRUE) {
if(counter % 2 == 0)
P(as);
print("A"); // and whatever A does
counter++;
if(counter % 2 == 0)
V(bs);
}
}
B() {
P(bs);
print("B"); // and whatever B does
V(as);
}
The idea is that A waits for B on every 2nd turn (execept the 0th).

I think that the general idea is correct, but the terminology is rather strange. Wait-signal pair is usually used for condition variables (although e.g. POSIX semaphorese use post/wait).
I suggest you substitue the wait with semaphore_down and signal with semaphore_up.

Related

Process not terminated causing a "too many processes" error

It is my first time using spin and I am encountering an error that I do not understand. I am aware that the processes terminates in the same order they are created thus I don't understand why the process of the function I call in a loop does not terminate.
Here is a very simplified version of my code :
int limit;
proctype f() {
limit--;
printm(limit)
run g();
}
proctype g() {
limit++;
}
init {
limit = 5;
do
:: (limit > 0) -> run f();
od
}
The limit variable is created so there is not more than 5 processes f running at the same time. The processes g does terminate but f don't. So I get the error : too many processes
I would like to know why f does not terminate and if there is another way to do that?
Your question is based on a false premise: it isn't true that there are never more than 5 processes in your system.
In fact, there can be any number of processes of type f(), because there is absolutely no guarantee that the instruction:
limit--;
is executed right after the process is created with
run f();
It is possible that the process scheduler lets init() execute for several (tens, hundreds, more..) loop iterations before it preempts it and gives a chance to some f() to execute anything.
If a process g() is created, then this can clearly terminate.
If a process f() is created, this can terminate only if there aren't already 255 processes in the system and it is the process f() with the highest pid, so that it does not have to wait for other processes.
The init() process can never terminate.
As a possible fix, you might want to try to look into _nr_pr:
int limit = 5;
proctype f() {
printm(limit)
}
init {
do
:: (_nr_pr <= (limit + 1)) ->
run f();
od
}

why while loop is not needed in sem_wait?

I am trying to compare produer consumer problem implementation using cond variable and semaphores.
Implementation using cond variable:
acquire(m); // Acquire this monitor's lock.
while (!p) { // While the condition/predicate/assertion that we are waiting for is not true...
wait(m, cv); // Wait on this monitor's lock and condition variable.
}
// ... Critical section of code goes here ...
signal(cv2); -- OR -- notifyAll(cv2); // cv2 might be the same as cv or different.
release(m);
Implementation using semaphore:
produce:
P(emptyCount)
P(useQueue)
putItemIntoQueue(item)
V(useQueue)
V(fullCount)
why semaphore implementation is not using while loop to check the condition like in cond variable implementation.?
while (!p) { // While the condition/predicate/assertion that we are waiting for is not true...
wait(m, cv); // Wait on this monitor's lock and condition variable.
}
Why do you need a while loop while waiting for a condition variable
Grabbing a semaphore does use a tight loop internally, just like the cond version, but it yields execution back to the scheduler in each iteration to not waste resources like a busy loop would.
When the scheduler has executed some other process for a while, it yields execution back to your thread. If the semaphore is available now, it is grabbed; otherwise it yields back to the scheduler to let some other process run some more before retrying.

How many processes are created in the program when using fork() in a condition?

I'm having trouble to understand how fork() works when it is used as a condition. I know that fork() creates a child process as an exact copy of the parent process. My question is, how many processes are created in the following program? Here is the code:
int global = 0;
int main() {
while(global < 5 && !fork()) {
sleep(1);
global += 1;
}
printf("%d\n", global);
return 0;
}
I was a assuming that for each fork() call, every process that is already running will create a child process and continue like that as long as the variable global reaches the value of 5.
The fork() call returns 0 in the child and the pid of the child in the parent.
Therefore, in the parent, the second condition will evaluate to 0, and the loop will exit and then print. In the child, the second condition will evaluate to non-zero, and the loop will fork again with a higher value of global (which is inherited).
Thus, we will see a total of 5 new processes in addition to the parent.

In SPIN/Promela, how to receive a MSG from a channel in the correct way?

I read the spin guide yet there is no answer for the following question:
I have a line in my code as following:
Ch?x
where Ch is a channel and x is channel type (to receive MSG)
What happens if Ch is empty? will it wait for MSG to arrive or not?
Do i need to check first if Ch is not empty?
basically all I want is that if Ch is empty then wait till MSG arrives and when it's arrive continue...
Bottom line: the semantics of Promela guarantee your desired behaviour, namely, that the receive-operation blocks until a message can be received.
From the receive man page
EXECUTABILITY
The first and the third form of the statement, written with a single
question mark, are executable if the first message in the channel
matches the pattern from the receive statement.
This tells you when a receive-operation is executable.
The semantics of Promela then tells you why executability matters:
As long as there are executable transitions (corresponding to the
basic statements of Promela), the semantics engine will select one of
them at random and execute it.
Granted, the quote doesn't make it very explicit, but it means that a statement that is currently not executable will block the executing process until it becomes executable.
Here is a small program that demonstrates the behaviour of the receive-operation.
chan ch = [1] of {byte};
/* Must be a buffered channel. A non-buffered, i.e., rendezvous channel,
* won't work, because it won't be possible to execute the atomic block
* around ch ! 0 atomically since sending over a rendezvous channel blocks
* as well.
*/
short n = -1;
proctype sender() {
atomic {
ch ! 0;
n = n + 1;
}
}
proctype receiver() {
atomic {
ch ? 0;
n = -n;
}
}
init {
atomic {
run sender();
run receiver();
}
_nr_pr == 1;
assert n == 0;
/* Only true if both processes are executed and if sending happened
* before receiving.
*/
}
Yes, the current proctype will block until a message arrives on Ch. This behavior is described in the Promela Manual under the receive statement. [Because you are providing a variable x (as in Ch?x) any message in Ch will cause the statement to be executable. That is, the pattern matching aspect of receive does not apply.]

create a process tree in C

How would I approach creating a process hierarchy that would look like a balanced ternary tree of depth N? ... meaning each process has 3 children so there would be (3^N-1)/2 processes in a tree of depth N. To create the new processes, I only want to use fork().
This is what I have so far but I don't think it works because I don't deal with process IDs and also I really don't think I should do this recursively:
void createTernaryTree(int n) {
if((n-1) == 0) return;
else {
int x;
for(x=0; x<3; x++) {
fork();
createTernaryTree(n-1);
}
}
}
Thanks,
Hristo
This bit does not look right to me:
for(x=0; x<3; x++) {
fork();
createTernaryTree(n-1);
}
The problem is that both the parent and the child continue looping and do the recursion.
Based on the return from fork (0 in the child, > 0 in the parent, -1 on error), you should decide whether to loop or recurse.
The code shown would do the job The code shown would nearly do the job (but there's a subtle problem). The other difficulty would be showing that it does the job.
The problem is that the code doesn't behave differently for the child and the parent processes after the fork. The parent process needs to complete its loop. Each child needs to restart a loop at the next level:
for (int x = 0; x < 3; x++) // C99
{
if (fork() == 0)
{
createTernaryTree(n-1);
break; // Per comment from R Samuel Klatchko
}
}
pause(); // See below
You could (should) add a 'pause();' call after the loop; this would send the parent process into suspended animation until it receives a signal. You could then show that you have a tree of processes. Alternatively, use 'sleep(30)' or some other way of suspending the processes. You don't want them to exit immediately; they'll do that too quickly for you to be able to demonstrate the tree structure.
In theory, you might want to track whether 'fork()' succeeds; in practice, it isn't clear what you'd do differently except, perhaps, not try to create the second child if the first fails (but that's likely to fail anyway, so blindly trying is probably best in the circumstances - but remember that in other situations, it would usually matter a lot).
Trees are inherently recursive structures; using recursion to manage them is often the neatest way to deal with them. This looks like it is tail recursion which means that it can be converted into a looping structure fairly easily. However, managing a data structure to keep tabs on what is happening is going to be harder than just doing it recursively.