我目前正在玩信号量并试图理解它们。我正在尝试遵循一个教程,该教程要求我编辑示例代码以使程序运行两个进程,这两个进程轮流将歌词输出到歌曲中(“桶中有一个洞”)。
我的问题是,当我在程序中添加更多歌曲行时,这些过程不会交替,但是当只有两行时它们可以正常工作。
一个进程处理 Liza 的部分,另一个处理 Henry 的部分。这是我的代码:
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
#define KEY 87654 //Unique semaphore key
int main()
{
int id; /* Number by which the semaphore is known within a program */
union semun {
int val;
struct semid_ds *buf;
ushort * array;
} argument;
argument.val = 1;
/* Create the semaphore with external key KEY if it doesn't already
exists. Give permissions to the world. */
id = semget(KEY, 1, 0666 | IPC_CREAT);
/* Always check system returns. */
if(id < 0) {
fprintf(stderr, "Unable to obtain semaphore.\n");
exit(0);
}
/* What we actually get is an array of semaphores. The second
argument to semget() was the array dimension - in our case
1. */
/* Set the value of the number 0 semaphore in semaphore array
# id to the value 0. */
if( semctl(id, 0, SETVAL, argument) < 0) {
fprintf( stderr, "Cannot set semaphore value.\n");
} else {
fprintf(stderr, "Semaphore %d initialized.\n", KEY);
}
int pid=fork();
if(pid) {
struct sembuf operations[1];
int retval; /* Return value from semop() */
/* Get the index for the semaphore with external name KEY. */
id = semget(KEY, 1, 0666);
if(id < 0){
/* Semaphore does not exist. */
fprintf(stderr, "Program sema cannot find semaphore, exiting.\n");
exit(0);
}
operations[0].sem_num = 0;
/* Which operation? Subtract 1 from semaphore value : */
operations[0].sem_op = -1;
/* Set the flag so we will wait : */
operations[0].sem_flg = 0;
while(1){
//Process 1
//wait
operations[0].sem_op = -1;
retval = semop(id, operations, 1);
//critical section
printf("Then mend it, dear Henry, dear Henry, dear Henry, \n");
printf("Then mend it, dear Henry, dear Henry, mend it. \n");
fflush(stdout);
int stime=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stime);
sleep(stime);
printf("With a straw, dear Henry, dear Henry, dear Henry, \n");
printf("With a straw, dear Henry, dear Henry, with a straw. \n");
fflush(stdout);
int stim1e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim1e);
sleep(stim1e);
printf("Then cut it, dear Henry, dear Henry, dear Henry, \n");
printf("Then cut it, dear Henry, dear Henry, cut it. \n");
fflush(stdout);
int stim2e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim2e);
sleep(stim2e);
printf("With a knife, dear Henry, dear Henry, dear Henry, \n");
printf("With a knife, dear Henry, dear Henry, with a knife. \n");
fflush(stdout);
int stim3e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim3e);
sleep(stim3e);
printf("Then sharpen it, dear Henry, dear Henry, dear Henry \n");
printf("Then sharpen it, dear Henry, dear Henry, sharpen it. \n");
fflush(stdout);
int stim4e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim4e);
sleep(stim4e);
printf("On a stone, dear Henry, dear Henry, dear Henry, \n");
printf("On a stone, dear Henry, dear Henry, a stone. \n");
fflush(stdout);
int stim5e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim5e);
sleep(stim5e);
printf("Well wet it, dear Henry, dear Henry, dear Henry, \n");
printf("Well wet it, dear Henry, dear Henry, wet it. \n");
fflush(stdout);
int stim6e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim6e);
sleep(stim6e);
printf("try water, dear Henry, dear Henry, dear Henry, \n");
printf("try water, dear Henry, dear Henry, water. \n");
fflush(stdout);
int stim7e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim7e);
sleep(stim7e);
printf("In a bucket, dear Henry, dear Henry, dear Henry, \n");
printf("In a bucket, dear Henry, dear Henry, a bucket. \n");
fflush(stdout);
int stim8e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim8e);
sleep(stim8e);
printf("Use your head, then! dear Henry, dear Henry, dear Henry, \n");
printf("Use your head, then! dear Henry, dear Henry, use your head! \n");
fflush(stdout);
operations[0].sem_op = 1;
//signal
retval = semop(id, operations, 1);
}
}else{
//Process 2
struct sembuf operations[1];
int retval; /* Return value from semop() */
/* Get the index for the semaphore with external name KEY. */
id = semget(KEY, 1, 0666);
if(id < 0){
/* Semaphore does not exist. */
fprintf(stderr, "Program sema cannot find semaphore, exiting.\n");
exit(0);
}
operations[0].sem_num = 0;
/* Which operation? Subtract 1 from semaphore value : */
operations[0].sem_op = -1;
/* Set the flag so we will wait : */
operations[0].sem_flg = 0;
while(1){
//wait
operations[0].sem_op = -1;
retval = semop(id, operations, 1);
//critical section
printf("There's a hole in the bucket, dear Liza, dear Liza, \n");
printf("There's a hole in the bucket, dear Liza, a hole. \n");
fflush(stdout);
int stim9e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim9e);
sleep(stim9e);
printf("With what shall I mend it, dear Liza, dear Liza? \n");
printf("With what shall I mend it, dear Liza, with what? \n");
fflush(stdout);
int stim0e=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stim0e);
sleep(stim0e);
printf("The straw is too long, dear Liza, dear Liza, \n");
printf("The straw is too long, dear Liza, too long, \n");
fflush(stdout);
int stimae=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stimae);
sleep(stimae);
printf("The knife is too dull, dear Liza, dear Liza, \n");
printf("The knife is too dull, dear Liza, too dull. \n");
fflush(stdout);
int stimse=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stimse);
sleep(stimse);
printf("On what shall I sharpen it, dear Liza, dear Liza? \n");
printf("On what shall I sharpen it, dear Liza, on what? \n");
fflush(stdout);
int stimde=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stimde);
sleep(stimde);
printf("The stone is too dry, dear Liza, dear Liza, \n");
printf("The stone is too dry, dear Liza, too dry. \n");
fflush(stdout);
int stimwe=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stimwe);
sleep(stimwe);
printf("With what shall I wet it, dear Liza, dear Liza? \n");
printf("With what shall I wet it, dear Liza, with what? \n");
fflush(stdout);
int stimqe=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stimqe);
sleep(stimqe);
printf("In what shall I fetch it, dear Liza, dear Liza? \n");
printf("In what shall I fetch it, dear Liza, in what? \n");
fflush(stdout);
int stimee=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stimee);
sleep(stimee);
printf("There's a hole in my bucket, dear Liza, dear Liza \n ");
printf("There's a hole in my bucket, dear Liza, a hole. \n ");
fflush(stdout);
//signal
operations[0].sem_op = 1;
retval = semop(id, operations, 1);
}
}
}