多个进程中的静态变量(信号)

时间:2016-10-16 13:37:24

标签: c linux unix static fork

我有两个运行test.c的进程。 test.c中有一个执行execlp的信号处理程序。在test.c中,我有一个静态变量,它只需要初始化一次,并且每次在execlp调用之前递增。当任一过程达到99时,它们就会退出。

不幸的是,现在,它没有增加,我的猜测是因为有2个进程,每个进程都有静态变量的副本。这是test.c:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

static int i = 0;

static int foo(int j)
{
    printf("In the foo...\n");
    j++;
    printf("%d\n", j);
    return j;
}


void main(int argc, char *argv[])
{
    int pid, pid2, k;
    int *h = malloc(sizeof(int));
    int g = 0;
    h = &g;

    static char s[15];


    pid = fork();
    if (pid > 0)
    {
        sleep(1);
    }

    if (pid == 0)
    {
        k = foo(*h);

        sprintf(s, "%d", k);
        if (k >= 99)
        {
            printf("k=99\n");
            exit(0);        
        }
        execlp("./a.out", "forktest", s, NULL);
    }

    pid2 = fork();

    if (pid2 == 0)
    {

        k = foo(*h);

        sprintf(s, "%d", k);
        if (k >= 99)
        {
            printf("k=99\n");
            exit(0);        
        }
        execlp("./a.out", "forktest", s, NULL);

    }

    wait(pid2);
    wait(pid);
}

任何人都可以解释为什么存在无限循环?为什么静态变量不会增加?

谢谢。

2 个答案:

答案 0 :(得分:0)

在此使用进程间通信概念(管道,fifo,共享内存),execlp函数用新程序覆盖当前程序的内存。因此,当你调用execlp时,你的程序会被刷新并从开始开始,而static int i总是为0。

我建议使用pipe Refer this

答案 1 :(得分:0)

如果要在进程之间使用共享内存的概念,则需要使用内存投影(mmap函数)。 在您的代码中,变量&#39; h&#39;是三个进程之间的共享变量。它应该使用mmap函数定义并在主进程中初始化,然后在两个子进程中递增。

您的两个问题的答案是相关的:两个子进程中的任何一个从不退出(退出(0)),因为if(k&gt; = 99)永远不会被满足。这是由于非共享变量h不会增加。

我宁愿使用while循环和返回类型main函数。 顺便说一句,你不需要&#39;&#39; varibale,你可以直接初始化&#39; h&#39;。并且不需要将函数foo声明为静态(静态函数仅在您希望它们仅在定义它们的文件中可见时才有用)。缓冲区&#39;可以声明为非静态(它只是一个包含k值的缓冲区)

以下是您的代码的修改版本,它可以编译并正常工作。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>

int foo(int* j) 
{   
    printf("In the foo...\n");

    (*j)++;

    printf("%d\n", *j);

    return *j;
}

int main(void) 
{

    int pid, pid2, k;
    char s[15];

    int * h = (int*)mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

    if (h == MAP_FAILED) {
        printf("map failed\n");
        return -1;
    }

    *h = 0;
    pid = fork();

    if (pid < 0) {
        printf("fork failed pid\n");

        return -1;
    }

    if (pid > 0) {
        sleep(1);
    }
    else {

       while(1) {       
        k = foo(h);

        sprintf(s, "%d", k);

        if (k>=99) {
            printf("k>=99\n");
            printf("%s\n", s);
            exit(0);

        }

        execlp("./a.out", "forktest", s, NULL);

      }
    }

    pid2 = fork();

    if (pid2 < 0) {
        printf("fork failed pid2\n");
    }

    if (pid2 > 0) {
        sleep(1);
    }
    else {

       while(1) {   
        k = foo(h);

        sprintf(s, "%d", k);

        if (k>=99) {

            printf("k>=99\n");

            exit(0);
        }

        execlp("./a.out", "forktest", s, NULL);

        }
    }

    wait(pid);
    wait(pid2);

    return 0;
}

这是输出(只有最后一个字符串)点击链接: output