如何使用信号量让 n 个进程等待?
How do I get n processes to wait using semaphore?
我再次需要你的帮助...
我正在尝试用 C 语言开发一个程序,它执行以下操作:
managerProcess
创建 NUM_PROCESSES
Student
个进程。
每个 Student
进程一旦创建,就会等待创建其他 Student
进程,直到创建进程数。
创建所有 Student
个进程后,它们开始执行与此问题无关的工作。
重要事项:每个 Student
进程必须具有相同的代码。
这是我写的一些代码:
pid_t run_child(Student s, int index, int (*function)(Student s, int index)){
pid_t p;
p = fork();
if (p == -1)
return -1;
else if (!p)
exit(function(s, index));
else
return p;
}
int child_process(Student s, int index){
//This printf is executed NUM_PROCESSES times
printf("Child Process %d has been created\n", getpid());
//Once reached this point each Process running this function will do other things
/*SOME OTHER CODE STUDENT PROCESSES EXECUTE*/
printf("%d Student Processes Created\n", NUM_PROCESSES);
return EXIT_SUCCESS;
}
最后 main.c
文件:
int main(int argc, char *argv[]){
pid_t child_pid[NUM_PROCESSES];
int child_status[NUM_PROCESSES];
int i;
int status;
status = EXIT_SUCCESS;
for (i = 0; i < NUM_PROCESSES; i++) {
Student s;
child_pid[i] = run_child(s, i, child_process);
if (child_pid[i] == -1) {
fprintf(stderr, "Cannot fork a child process: %s.\n", strerror(errno));
status = EXIT_FAILURE;
}
}
return status;
}
您可能会注意到,上面的代码创建了 NUM_PROCESSES
Student
个进程,这很好。
我想要做的是每个 Student
进程等待所有 NUM_PROCESSES
Student
进程创建,然后他们才开始做其他事情。
我怎样才能使用下面开发的 Semaphore
来实现?
//Creates ONE Semaphore
int createSemaphore(key_t semaphoreKey){
int semaphoreId = semget(semaphoreKey, 1, 0666 | IPC_CREAT);
if(semaphoreId == -1){
printf(RED "Semaphore Creation failed\n"RESET);
return -1;
}
return semaphoreId;
}
//Creates a set of Semaphores with numSems Semaphores
int createSemaphoreSet(key_t semaphoreKey, int numSems){
int semaphoreId = semget(semaphoreKey, numSems, 0666 | IPC_CREAT);
if(semaphoreId == -1){
printf(RED "Semaphore Set Creation Failed\n" RESET);
return -1;
}
return semaphoreId;
}
//Decreases semaphores value by 1
void semaphoreWait(int semaphoreId, int semaphoreNumber){
struct sembuf buffer;
buffer.sem_num = semaphoreNumber;
buffer.sem_op = -1;
buffer.sem_flg = 0;
int done = semop(semaphoreId, &buffer, 1);
if(done == -1){
printf(RED "Wait on Semaphore %d failed\n" RESET, semaphoreNumber);
return;
}
}
//Increments semaphore's value by 1
void semaphoreSignal(int semaphoreId, int semaphoreNumber){
struct sembuf buffer;
buffer.sem_num = semaphoreNumber;
buffer.sem_op = 1;
buffer.sem_flg = 0;
int done = semop(semaphoreId, &buffer, 1);
if(done == -1){
printf(RED "semaphoreSignal Failed on Semaphore %d\n" RESET, semaphoreNumber);
return;
}
}
希望我已经说清楚了。
非常感谢
根据您使用的 System-V 风格的信号量,一般方案最好是这样的:
parent进程通过semget()
创建或打开信号量,并通过semctl()
.
[=35将其值初始化为0 =]
parent分叉所有children.
每个child通过semop()
对信号量执行decrement-by-one操作。例如,
struct sembuf semops = { .sem_num = 0, .sem_op = -1 };
int result = semop(semid, &semops, 1);
每个 child 将阻塞,直到它可以执行此操作而不会使信号量的值为负。
parent 使用 semop()
将信号量的值增加 child 个进程数。此信号量操作不阻塞,完成后,所有children都可以进行。
struct sembuf semops2 = { .sem_num = 0, .sem_op = NUM_PROCESSES };
int result2 = semop(semid, &semops2, 1);
还有其他信号量操作组合可以实现您所描述的(以及更现代的信号量风格,您可以使用它们来执行其中的一些操作),但我敢说以上内容提供了标准 System-V 习语这样的任务。
我再次需要你的帮助...
我正在尝试用 C 语言开发一个程序,它执行以下操作:
managerProcess
创建 NUM_PROCESSES
Student
个进程。
每个 Student
进程一旦创建,就会等待创建其他 Student
进程,直到创建进程数。
创建所有 Student
个进程后,它们开始执行与此问题无关的工作。
重要事项:每个 Student
进程必须具有相同的代码。
这是我写的一些代码:
pid_t run_child(Student s, int index, int (*function)(Student s, int index)){
pid_t p;
p = fork();
if (p == -1)
return -1;
else if (!p)
exit(function(s, index));
else
return p;
}
int child_process(Student s, int index){
//This printf is executed NUM_PROCESSES times
printf("Child Process %d has been created\n", getpid());
//Once reached this point each Process running this function will do other things
/*SOME OTHER CODE STUDENT PROCESSES EXECUTE*/
printf("%d Student Processes Created\n", NUM_PROCESSES);
return EXIT_SUCCESS;
}
最后 main.c
文件:
int main(int argc, char *argv[]){
pid_t child_pid[NUM_PROCESSES];
int child_status[NUM_PROCESSES];
int i;
int status;
status = EXIT_SUCCESS;
for (i = 0; i < NUM_PROCESSES; i++) {
Student s;
child_pid[i] = run_child(s, i, child_process);
if (child_pid[i] == -1) {
fprintf(stderr, "Cannot fork a child process: %s.\n", strerror(errno));
status = EXIT_FAILURE;
}
}
return status;
}
您可能会注意到,上面的代码创建了 NUM_PROCESSES
Student
个进程,这很好。
我想要做的是每个 Student
进程等待所有 NUM_PROCESSES
Student
进程创建,然后他们才开始做其他事情。
我怎样才能使用下面开发的 Semaphore
来实现?
//Creates ONE Semaphore
int createSemaphore(key_t semaphoreKey){
int semaphoreId = semget(semaphoreKey, 1, 0666 | IPC_CREAT);
if(semaphoreId == -1){
printf(RED "Semaphore Creation failed\n"RESET);
return -1;
}
return semaphoreId;
}
//Creates a set of Semaphores with numSems Semaphores
int createSemaphoreSet(key_t semaphoreKey, int numSems){
int semaphoreId = semget(semaphoreKey, numSems, 0666 | IPC_CREAT);
if(semaphoreId == -1){
printf(RED "Semaphore Set Creation Failed\n" RESET);
return -1;
}
return semaphoreId;
}
//Decreases semaphores value by 1
void semaphoreWait(int semaphoreId, int semaphoreNumber){
struct sembuf buffer;
buffer.sem_num = semaphoreNumber;
buffer.sem_op = -1;
buffer.sem_flg = 0;
int done = semop(semaphoreId, &buffer, 1);
if(done == -1){
printf(RED "Wait on Semaphore %d failed\n" RESET, semaphoreNumber);
return;
}
}
//Increments semaphore's value by 1
void semaphoreSignal(int semaphoreId, int semaphoreNumber){
struct sembuf buffer;
buffer.sem_num = semaphoreNumber;
buffer.sem_op = 1;
buffer.sem_flg = 0;
int done = semop(semaphoreId, &buffer, 1);
if(done == -1){
printf(RED "semaphoreSignal Failed on Semaphore %d\n" RESET, semaphoreNumber);
return;
}
}
希望我已经说清楚了。 非常感谢
根据您使用的 System-V 风格的信号量,一般方案最好是这样的:
parent进程通过
[=35将其值初始化为0 =]semget()
创建或打开信号量,并通过semctl()
.parent分叉所有children.
每个child通过
semop()
对信号量执行decrement-by-one操作。例如,struct sembuf semops = { .sem_num = 0, .sem_op = -1 }; int result = semop(semid, &semops, 1);
每个 child 将阻塞,直到它可以执行此操作而不会使信号量的值为负。
parent 使用
semop()
将信号量的值增加 child 个进程数。此信号量操作不阻塞,完成后,所有children都可以进行。struct sembuf semops2 = { .sem_num = 0, .sem_op = NUM_PROCESSES }; int result2 = semop(semid, &semops2, 1);
还有其他信号量操作组合可以实现您所描述的(以及更现代的信号量风格,您可以使用它们来执行其中的一些操作),但我敢说以上内容提供了标准 System-V 习语这样的任务。