首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C中使用信号量的并行处理和同步

C中使用信号量的并行处理和同步
EN

Stack Overflow用户
提问于 2016-01-02 20:16:31
回答 3查看 1.1K关注 0票数 0

问题:

  1. 我的进程是否并行运行?我希望有六个进程并行运行。
  2. 如何在无限循环中使用信号量同步这些进程(父进程和五个子进程)?输出结果是:1 2 3 4 5复位1 2 3 4 5复位等.
  3. 有什么简单明了的信号量文档吗?

代码:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

parentWithFiveChildren()
{   
    printf("1 "); //Parent
    fflush(stdout);

    int i, status;

    for (i = 2; i < 7; i++)
    {   
        sleep(1); 
        if (fork() == 0) //Child Processes
        {               
            if (i == 6) 
            {
                printf("reset "); 
                fflush(stdout);
                exit(0);
            }
            printf("%d ", i); 
            fflush(stdout);
            sleep(7); 
            exit(i); //Exiting child processes
        }
    }

    while ((wait(&status)) > 0)
    printf("\a");
    return 0;
}

int main(void)
{
    parentWithFiveChildren();
}

输出:

代码语言:javascript
复制
1 2 3 4 5 reset
EN

回答 3

Stack Overflow用户

发布于 2016-01-02 20:50:20

1.并行性

不,进程不是并行运行的(或者,至少,它们只在瞬间并行运行,一次只运行两个进程),,但是--这只是因为:

  1. sleep(1)给父进程很长的时间(至少一秒)什么也不做。
  2. 孩子在那一秒内结束并退出。

子操作中的打印代码是奇怪的;实际上,i == 6和其他操作之间没有区别。在main()中,return 0;exit(0);实际上是相同的--可能存在差异,但它们是模糊的,与代码无关。

您应该#include <sys/wait.h>,并且您应该收集死孩子的PID (和状态);这将使事情对您来说更清楚。

你也可以让孩子们报告睡眠一段时间(比如每人7秒)。这将使所有子进程“运行”(实际上是睡眠)并行运行,然后父进程等待子进程退出:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    printf("[PARENT] with pid %d\n", getpid()); 
    fflush(stdout);

    for (int i = 2; i < 7; i++)  // Odd loop conditions, but not wrong
    {   
        sleep(1); 
        if (fork() == 0)
        {   
            printf("[CHILD] with pid %d from parent with pid %d\n", getpid(), getppid()); 
            fflush(stdout);
            sleep(7);
            printf("[CHILD] with pid %d exiting with status %d\n", getpid(), i); 
            exit(i);
        }
    }

    int corpse;
    int status;
    while ((corpse = wait(&status)) > 0)
        printf("%d: child %d exited with status 0x%.4X\n", getpid(), corpse, status);
    return 0;
}

样本输出:

代码语言:javascript
复制
$ ./test-forking
[PARENT] with pid 13904
[CHILD] with pid 13905 from parent with pid 13904
[CHILD] with pid 13906 from parent with pid 13904
[CHILD] with pid 13907 from parent with pid 13904
[CHILD] with pid 13908 from parent with pid 13904
[CHILD] with pid 13909 from parent with pid 13904
[CHILD] with pid 13905 exiting with status 2
13904: child 13905 exited with status 0x0200
[CHILD] with pid 13906 exiting with status 3
13904: child 13906 exited with status 0x0300
[CHILD] with pid 13907 exiting with status 4
13904: child 13907 exited with status 0x0400
[CHILD] with pid 13908 exiting with status 5
13904: child 13908 exited with status 0x0500
[CHILD] with pid 13909 exiting with status 6
13904: child 13909 exited with status 0x0600
$

对代码的升级也会打印每一行输出的时间。

2.杀害

任何进程(在父进程创建的集合中)都可以使用kill()系统调用杀死它知道的任何其他进程(集合中的进程)。现在还不清楚你是想让第一个孩子还是最后一个孩子去杀死父母,还是别的什么。如果第一个孩子杀死了父母,那么第一个孩子将是唯一的孩子(因为延迟)。还不清楚为什么要在进程之间发送信号。

3.循环

是的,你可以做点什么-问题是,你到底想要什么。简单地多次打印parentchild并不需要多个进程。如果你想让父母说“我在这里”,而每个孩子定期说“我在这里”,你需要让孩子们循环和睡觉,父母在所有的孩子被创造之后循环和睡觉。做起来不难。

票数 4
EN

Stack Overflow用户

发布于 2016-01-02 20:44:10

问题3)。...Can我把主函数放在一个无限循环中.?

确定你能

代码语言:javascript
复制
int  main(void)
{
    int c=0;
    while((c != 'q') && (c != EOF))//loops until c == q (and c!=EOF)
    {
        c = getchar();//waits until stdin sees a "q", (i.e. from keyboard)

        //An EOF (-1) or `q` will exit the loop
        //any other input will allow execution flow to continue, 1 loop at a time.  
        //Add additional forking code here.           
        //for each loop, spawn a new thread.
        //All secondary threads spawned will run parallel to other threads.
    }
    //exiting here will kill all threads (secondary and primary.)
    return 0;
}
票数 2
EN

Stack Overflow用户

发布于 2016-01-02 20:40:01

1)是的,父进程和子进程是一个接一个的并行运行,您可以通过无限循环子进程并打印它的名称来看到这一点,而父进程和其他进程也在这样做。

2)是的,以下是如何:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/types.h>
#include <signal.h>

int main()
{
    pid_t pid;
    int i = 0;

    if ((pid = fork()) == 0)
    {
        if ((pid = getppid()) == -1)
        {
            fprintf(stderr, "child error: getppid()\n");
            exit(1);
        }
        if (kill(pid, 9) == -1)
        {
            fprintf(stderr, "child error: kill()\n");
            exit(1);
        }

        while (true)
        {
            printf ("child %d\n", ++i);
        }
    }
    else if (pid == -1)
    {
        fprintf(stderr, "error: fork()\n");
        return 1;
    }

    while (true)
    {
        printf("parent %d\n", ++i);
    }

    return 0;
}

3)如果您需要特定的模式,则需要进程间的通信和同步。建议

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34570279

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档