【发布时间】:2020-09-22 08:29:45
【问题描述】:
我有N 数量的孩子需要在循环中做一些工作,同时彼此同步。即,如果一个子进程处于其第 i 次迭代,则所有其他子进程都应处于第 i 次迭代。我需要将它们与信号量同步,但我找不到如何做到这一点。这是我写的代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/sem.h>
void sem_signal(int semid, int val) {
struct sembuf semaphore;
semaphore.sem_num = 0;
semaphore.sem_op = val;
semaphore.sem_flg = 0;
semop(semid, &semaphore, 1);
}
void sem_wait(int semid, int val) {
struct sembuf semaphore;
semaphore.sem_num = 0;
semaphore.sem_op = (-1 * val);
semaphore.sem_flg = 0;
semop(semid, &semaphore, 1);
}
int main() {
int sem_worker = semget(1, 1, 0700 | IPC_CREAT);
semctl(sem_worker, 0, SETVAL, 0);
int process_index = 0;
int N = 4, pid;
for (process_index = 0; process_index < N; process_index++) {
pid = fork();
if (pid == -1) {
printf("ERROR: cannot fork!\n");
return EXIT_FAILURE;
}
if (pid == 0)
break;
}
if (pid!=0) // parent
pause();
else {
int i = 0;
while (i < 3) {
printf("process %d: i: %d\n", process_index, i);
sem_signal(sem_worker, 1); // increase the semaphore by one
sem_wait(sem_worker, N); // wait for all the other childs
i += 1;
}
}
}
但是当我运行它时,它在第一次迭代后无法继续。
process 0: i: 0
process 1: i: 0
process 3: i: 0
process 2: i: 0
process 0: i: 1
我明白为什么会这样。这是因为其中一个进程使信号量为 0 并继续下一次迭代,但所有其他进程仍在等待。那么我应该如何编写代码来解决这个问题呢?
P.S:我从其他地方获取了 sem_signal 和 sem_wait 函数,所以我不确定它是如何工作的,但我确信它们工作正常。例如,如果我在父进程中写入 sem_wait(my_sem, num_of_children) 以等待所有子进程,并在子进程完成时将 my_sem 增加 1,则它可以工作。
【问题讨论】:
-
您的代码没有任何意义。但是,您描述的是一个障碍,您应该能够找到可以帮助您解决此问题的资源。
-
好吧,我写这个只是为了证明我的目的,我知道它不会起作用。如果您在谈论
main以上的功能,我不是它们的作者 :D 感谢您的建议,我会看看它。 -
@EOF 这似乎是完全不同的概念。这是我的任务的一部分,据说“你必须使用信号量进行进程同步”所以我不能使用 barriers。你还有什么想法吗?
-
不,它不是不同的概念。如果您阅读例如的描述pthread_barrier_wait(),您会发现它正是您需要的。您可以从几个信号量合成一个屏障,请参阅此免费提供的book
标签: c synchronization semaphore barrier