等待所有进程到达程序中的某个点,然后恢复
Wait for all processes reach some point in program, then resume
我有一个通过 fork() 创建许多进程的应用程序。在某些时候,我想暂停它们并等待它们全部完成之前的任务。然后一次启动它们。
for (int i = 0; i < N; i++)
{
if(fork() == 0)
{
//some operations here
<----- wait here for all N forked processes
//some operations I want all processes start at similiar time
我不希望 children 中的任何一个退出。
与进程通信的方式有很多种,称为IPC(Inter Process Communication)。这取决于您需要发送什么样的信息,有多大等。过程信号也是控制过程的一种方式。
这里有一些资源可以帮助您入门:
- 我个人喜欢 Beej Guides,它很棒、清晰、简洁而且免费!
http://beej.us/guide/bgipc/
- 还有 CodeSourcery LLC 的高级 Linux 编程。
http://www.advancedlinuxprogramming.com/
- 当然,一旦您对基础知识有了一些了解,您可以更具体地查找 http://whosebug.com,即在这里:-)
您可以使用像信号量这样的同步结构。
在你想要停止所有孩子的代码点让他们在队列中等待(调用 wait on a semaphore with 0 as initial value )of semaphore 因此他们都会阻塞。
在 parent 然后你可以发出信号量并因此启动它们。
为此,我强烈推荐 Message Passing Interface (MPI),因为它具有 MPI_Barrier
,您可以使用它来准确地实现您想要的,几乎不需要您自己编写代码的逻辑。还有其他选择,例如 OpenMP。
我已经通过群组信号解决了这个问题:
for (int i = 0; i < N; i++)
{
if(fork() == 0)
{
/* save first process pid in shared memory */
if(localID == 0)
*sh_temp = getpid();
/* wait in all processes for shared memory with group id to be set */
while(*sh_temp == 0)
usleep(10000);
/* set group id to first process PID */
setpgid(getpid(), *sh_temp);
//some operations here
fprintf(stderr, "Process %d paused... W8ing for signal to resume\n", getpid());
raise(SIGSTOP);
//some operations I want all processes start at similiar time
}
}
if(parentPID == getpid())
{
fprintf(stderr, "Wake-up signal sent to group %ld.\n", *sh_temp);
killpg(*sh_temp, SIGCONT);
}
但是 - 如果有人有更好的解决方案请 post 它。
这似乎是为信号量量身定做的。具体来说,这很容易用 "System V semaphores" 实现。参见 semget(2)
和 semop(2)
。
想法是在父级中获得一个信号量,将其值初始化为 N
,然后让每个子级 "ready" 将值减 1。所有子级都等待结果变成 0。瞧。
这是一个示例程序
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define N 5
int main(int ac, char **av)
{
int i, n, sem_id;
sem_id = semget(IPC_PRIVATE, 1, 0777);
struct sembuf buf;
buf.sem_num = 0;
buf.sem_flg = 0;
// Initialize semaphore value to N
buf.sem_op = N;
n = semop(sem_id, &buf, 1);
// All children will do the same thing:
// decrement semaphore value by 1
// wait for semaphore value == 0
for (i = 0; i < N; ++i) {
if (fork() == 0) {
printf("Child %d (%d) started\n", i, getpid());
sleep(i + 1); // Sleep awhile.
buf.sem_op = -1;
n = semop(sem_id, &buf, 1);
buf.sem_op = 0;
n = semop(sem_id, &buf, 1);
printf("Child %d (%d) done\n", i, getpid());
return 0;
}
}
return 0;
}
我有一个通过 fork() 创建许多进程的应用程序。在某些时候,我想暂停它们并等待它们全部完成之前的任务。然后一次启动它们。
for (int i = 0; i < N; i++)
{
if(fork() == 0)
{
//some operations here
<----- wait here for all N forked processes
//some operations I want all processes start at similiar time
我不希望 children 中的任何一个退出。
与进程通信的方式有很多种,称为IPC(Inter Process Communication)。这取决于您需要发送什么样的信息,有多大等。过程信号也是控制过程的一种方式。
这里有一些资源可以帮助您入门:
- 我个人喜欢 Beej Guides,它很棒、清晰、简洁而且免费! http://beej.us/guide/bgipc/
- 还有 CodeSourcery LLC 的高级 Linux 编程。 http://www.advancedlinuxprogramming.com/
- 当然,一旦您对基础知识有了一些了解,您可以更具体地查找 http://whosebug.com,即在这里:-)
您可以使用像信号量这样的同步结构。 在你想要停止所有孩子的代码点让他们在队列中等待(调用 wait on a semaphore with 0 as initial value )of semaphore 因此他们都会阻塞。
在 parent 然后你可以发出信号量并因此启动它们。
为此,我强烈推荐 Message Passing Interface (MPI),因为它具有 MPI_Barrier
,您可以使用它来准确地实现您想要的,几乎不需要您自己编写代码的逻辑。还有其他选择,例如 OpenMP。
我已经通过群组信号解决了这个问题:
for (int i = 0; i < N; i++)
{
if(fork() == 0)
{
/* save first process pid in shared memory */
if(localID == 0)
*sh_temp = getpid();
/* wait in all processes for shared memory with group id to be set */
while(*sh_temp == 0)
usleep(10000);
/* set group id to first process PID */
setpgid(getpid(), *sh_temp);
//some operations here
fprintf(stderr, "Process %d paused... W8ing for signal to resume\n", getpid());
raise(SIGSTOP);
//some operations I want all processes start at similiar time
}
}
if(parentPID == getpid())
{
fprintf(stderr, "Wake-up signal sent to group %ld.\n", *sh_temp);
killpg(*sh_temp, SIGCONT);
}
但是 - 如果有人有更好的解决方案请 post 它。
这似乎是为信号量量身定做的。具体来说,这很容易用 "System V semaphores" 实现。参见 semget(2)
和 semop(2)
。
想法是在父级中获得一个信号量,将其值初始化为 N
,然后让每个子级 "ready" 将值减 1。所有子级都等待结果变成 0。瞧。
这是一个示例程序
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define N 5
int main(int ac, char **av)
{
int i, n, sem_id;
sem_id = semget(IPC_PRIVATE, 1, 0777);
struct sembuf buf;
buf.sem_num = 0;
buf.sem_flg = 0;
// Initialize semaphore value to N
buf.sem_op = N;
n = semop(sem_id, &buf, 1);
// All children will do the same thing:
// decrement semaphore value by 1
// wait for semaphore value == 0
for (i = 0; i < N; ++i) {
if (fork() == 0) {
printf("Child %d (%d) started\n", i, getpid());
sleep(i + 1); // Sleep awhile.
buf.sem_op = -1;
n = semop(sem_id, &buf, 1);
buf.sem_op = 0;
n = semop(sem_id, &buf, 1);
printf("Child %d (%d) done\n", i, getpid());
return 0;
}
}
return 0;
}