我有两个运行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);
}
任何人都可以解释为什么存在无限循环?为什么静态变量不会增加?
谢谢。
答案 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