Having a hard time with semaphores

I am trying to write a really simple program that uses semaphores between a parent and child process. I create a semaphore, I fork the process, and then I have both the parent and the child wait for the semaphore to be zero. When either process gets control of the semaphore, they increment it, output a message and take input from the keyboard, then set it to zero again and repeat in a loop. What I am looking for the program to do is pass control of the semaphore between child and parent process back and forth evenly, with the child having control at one time, then releasing it, then the parent picking it up and doing the same.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

union semun
{
	int val;
	struct semid_ds *buf;
	ushort *array;
};

int main()
{
	int i,j; 
  	int pid;
  	int semid; /* semid of semaphore set */
  	key_t key = 1234; /* key to pass to semget() */
  	int semflg = IPC_CREAT | 0666; /* semflg to pass to semget() */
  	int nsems = 1; /* nsems to pass to semget() */
  	int nsops; /* number of operations to do */
	int num;
  	struct sembuf *sops = (struct sembuf *) malloc(2*sizeof(struct sembuf)); 

	if ((semid = semget(key, nsems, semflg)) == -1)
	{
		perror("/nsemget: semget failed/n");
		exit(1);
	}
	else
	{
		printf("\nsemget succeeeded. The id is =\%d\n", semid);
	}

	if ((pid = fork()) < 0)
	{
		perror("fork");
		exit(1);
	}

	if (pid == 0)
	{
		i = 0;
		nsops = 2;
		while (i < 4)
		{
			sops[0].sem_num = 0;
			sops[0].sem_op = 0;
			sops[0].sem_flg = 0;			

			sops[1].sem_num = 0;
			sops[1].sem_op = 1;
			sops[1].sem_flg = 0;

			if (( j = semop(semid, sops, nsops)) == -1)
			{
				perror("child semop failed");
			}
			else
			{
				printf("\nchild has it.");
				sleep(3);
				i++;
				nsops = 1;
				sops[0].sem_num = 0;
				sops[0].sem_op = -1;
				sops[0].sem_flg = 0;
				
				if ((j = semop(semid, sops, nsops)) == -1)
				{
					perror("child semop failed");
				}
				else
				{
					printf("child process gives it up");
					i++;
					sleep(3);
				}
			}
		}
	}
	else
	{
		i = 0;
                nsops = 2;
                while (i < 4)
                {
                        sops[0].sem_num = 0;
                        sops[0].sem_op = 0;
                        sops[0].sem_flg = 0;

                        sops[1].sem_num = 0;
                        sops[1].sem_op = 1;
                        sops[1].sem_flg = 0;

                        if (( j = semop(semid, sops, nsops)) == -1)
                        {
                                perror("parent semop failed");
                        }
                        else
                        {
                                printf("\nparent has it.");
				sleep(3);
                                i++;
                                nsops = 1;
                                sops[0].sem_num = 0;
                                sops[0].sem_op = -1;
                                sops[0].sem_flg = 0;

                                if ((j = semop(semid, sops, nsops)) == -1)
                                {
                                        perror("parent semop failed");
                                }
                                else
                                {
                                        printf("parent process gives it up");
                                        i++;
					sleep(3);
                                }
                        }
                }

	 }
	return 0;
}


the output I am expecting is something like this:

child has it. child process gives it up. 
parent has it. parent process gives it up.
child has it. child process gives it up. 
parent has it. parent process gives it up.
child has it. child process gives it up. 
parent has it. parent process gives it up.
child has it. child process gives it up. 
parent has it. parent process gives it up.
child has it. child process gives it up. 
parent has it. parent process gives it up.


Instead this is what I am getting is the following:


parent has it.
child has it
child process gives it up
parent process gives it up
[system hangs]


Any ideas? Really appreciate some help.
you reset your nsops to 1 and never go back to 2, so on the second iteration of the loop, semop() at line 55 and 96 just waits for zero, and never increments the semaphore.
Also you increment i by 2 on every iteration.
Last edited on
Topic archived. No new replies allowed.