Issue
I'd like to print 1 and 2 into console consequently. Desired output would be 121212121212.... 1s are printed by the child process. 2s are printed by the parent process. Processes are initiated by fork. The problem is that I get output like 11111222121212122222. Here is my code so far
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main (int argc, char * argv[])
{
pid_t pid;
key_t key;
int semid;
int result;
int counter;
struct sembuf buf[1];
key = ftok("./one_two", 1);
semid = semget(key, 2, 0666|IPC_CREAT);
buf[0].sem_num = 0;
buf[0].sem_flg = SEM_UNDO;
buf[1].sem_num = 1;
buf[1].sem_flg = SEM_UNDO;
semctl(semid, 0, SETVAL, 0);
buf[0].sem_op = -1;
buf[1].sem_op = 1;
semop(semid,(struct sembuf*) &buf[1], 1);
counter = 1;
pid = fork();
if (pid>0)
{
while(counter<100)
{
semop(semid,(struct sembuf*) &buf[0], 1);
write(2, "1", 2);
buf[0].sem_op = -1;
buf[1].sem_op = 1;
semop(semid,(struct sembuf*) &buf[1], 1);
counter++;
if(counter >10 ) return 1;
}
}
else
{
while(counter<10)
{semop(semid,(struct sembuf*) &buf[0], -1);
write(2, "2", 2);
buf[0].sem_op = -1;
buf[1].sem_op = 1;
semop(semid,(struct sembuf*) &buf[1], -1);
counter++;
if(counter >10 ) return 1;
}
}
return 0;
}
Solution
Your semaphore initialisation and usage is a little messy.
I guess that what you want is
Process 0 :
- must wait for semaphore 0 to be 0
- print "1"
- increase semaphore 0
- decrease semaphore 1
Process 1 :
- must wait for semaphore 1 to be 0
- print "2"
- decrease semaphore 0
- increase semaphore 1
Problems
You don't initialize all semaphores
semctl(semid, 0, SETVAL, 0);
is okay, but where issemctl(semid, 1, SETVAL, xx);
You call
semop
with strange argument, ok forsemop(semid,(struct sembuf*) &buf[1], 1);
: you want to play on semaphore 1, but what aboutsemop(semid,(struct sembuf*) &buf[0], -1);
??Your call
semop(semid, (struct sembuf *) &buf[1], 2)
is wrong: you try to play on semaphore 1 and 2, but yours are 0 and 1Your two processes don't wait for the same ending: first wait for
counter
to be more of 10, the second to be 10 or more)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int main(int argc, char *argv[])
{
pid_t pid;
key_t key;
int semid;
int counter;
struct sembuf buf[2];
key = ftok("./one_two", 1);
semid = semget(key, 2, 0666 | IPC_CREAT);
buf[0].sem_num = 0;
buf[0].sem_flg = SEM_UNDO;
buf[1].sem_num = 1;
buf[1].sem_flg = SEM_UNDO;
// set two semaphores values, don't use semop now
semctl(semid, 0, SETVAL, 1);
semctl(semid, 1, SETVAL, 0);
counter = 1;
pid = fork();
if (pid > 0) {
while (counter < 10) {
// wait 0 to be 0
buf[0].sem_op = 0;
// only read first semaphore
semop(semid, buf, 1);
write(2, "0", 2);
// decrease 1, increase 0");
buf[0].sem_op = 1;
buf[1].sem_op = -1;
semop(semid, buf, 2);
counter++;
}
} else {
while (counter < 10) {
// wait 1 to be 0
buf[1].sem_op = 0;
// only read second semaphore
semop(semid, buf+1, 1);
write(2, "1", 2);
// decrease 0, increase 1
buf[0].sem_op = -1;
buf[1].sem_op = 1;
semop(semid, buf, 2);
counter++;
if (counter > 10) {
puts("1: finished");
return 1;
}
}
}
return 0;
}
Answered By - Mathieu Answer Checked By - Terry (WPSolving Volunteer)