process - 下面的代码优先考虑修改共享变量的第一个孩子。如何消除此错误?
问题描述
我想将所有子进程所做的更改捕获到与父进程共享的变量中。
这是问题所在。父进程创建如下结构:
struct data
{
int pid;
int n;
char c;
};
它创建了 k 个进程,并且该结构与其所有子进程共享。变量c
被初始化为'n',它作为一个标志工作。
父母在随机时间(不超过 2 秒)后定期“唤醒”(从“睡眠”)检查 c 的值,如果 c 为 'y',则打印 n 的值(以及相应的 pid)并使 c 再次成为“n”。
另一方面,每个孩子 Pi,1≤i≤k,在随机时间量(不超过 2 秒)后定期“醒来”(从“睡眠”)检查 c 的值,如果 c 是 'n ' 然后将一些随机值分配给 n,连同它的进程 id 给 pid,将该值连同它自己的进程 id 一起打印,并使 c 为 'y'。
如果程序执行被用户终止(通过按 Ctrl-C),则父级及其所有子级应终止并应释放分配的内存。
这是代码:
typedef void (*sighandler_t)(int);
int shmid;
struct data
{
int pid;
int n;
char c;
};
void releaseSHM(int signum)
{
int status;
status = shmctl(shmid, IPC_RMID, NULL);
if (status == 0)
fprintf(stderr, "Remove shared memory with id = %d.\n", shmid);
else if (status == -1)
fprintf(stderr,"Cannot remove shared memory of id = %d.\n", shmid);
else
fprintf(stderr, "shmctl() returned wrong value while removing shared memory with id = %d.\n", shmid);
status = kill(0, SIGKILL);
exit(signum);
}
int main(int argc, char *argv[])
{
int num,k=5,i, p1;
struct data *s;
sighandler_t shandler;
shandler = signal(SIGINT, releaseSHM);
shmid = shmget(IPC_PRIVATE, sizeof(struct data), IPC_CREAT | 0777);
if(shmid==-1)
{
perror("shmget() failed");
exit(1);
}
s=(struct data *)shmat(shmid, NULL, 0);
s->c='n';
for(i=0;i<k;i++)
{
p1=fork();
if(p1==0)
{
while(1)
{
//shandler = signal(SIGINT, releaseSHM);
num=(rand()%3);
sleep(num);
if(s->c=='n')
{
s->n=rand();
s->pid=getpid();
printf("Child with pid %d set value of n as %d \n",s->pid,s->n);
s->c='y';
}
sleep(num);
}
}
else
{
while(1)
{
num=(rand()%3);
sleep(num);
if(s->c=='y')
printf("Parent reads value of n as %d set by child with process id %d \n",s->n, s->pid);
s->c='n';
}
}
}
return 0;
}
它给出的输出为:
Child with pid 13883 set value of n as 846930886
Parent reads value of n as 846930886 set by child with process id 13883
Child with pid 13883 set value of n as 1957747793
Parent reads value of n as 1957747793 set by child with process id 13883
Child with pid 13883 set value of n as 719885386
Parent reads value of n as 719885386 set by child with process id 13883
Child with pid 13883 set value of n as 596516649
Parent reads value of n as 596516649 set by child with process id 13883
Child with pid 13883 set value of n as 1350490027
Parent reads value of n as 1350490027 set by child with process id 13883
^CRemove shared memory with id = 15368197.
Killed
显然,它只捕获了一个子进程所做的更改,而没有给其他子进程机会。如何消除此错误?
如果需要任何其他信息,请在下面发表评论。
解决方案
您打算让父母和k个孩子争夺共享内存,但您只生成一个孩子,而不管k的值如何。
你这样写:
....
for (int i = 0; i < k; i++) {
pid_t child = fork();
if (child == 0) do_child_infinite_loop();
else do_parent_infinite_loop(); // <- BUG: the for loop never resumes
}
你的意思是这样做:
....
for (int i = 0; i < k; i++) {
pid_t child = fork();
if (child == 0) do_child_infinite_loop();
}
do_parent_infinite_loop();
一旦你解决了这个问题,你就可以继续进行其他调试:k 个子节点将相互踩踏彼此的更新,并且它们也共享相同的伪随机数序列。
推荐阅读
- javascript - Filter array in javascript
- node.js - 如果我的购物车数据库已经存在,如何使用 Sequelize 更新我的商品数量,如果不存在,如何创建它?
- java - 解析包含双引号的字符串
- r - 在 train 方法中,tuneGrid 和 trControl 有什么关系?
- arrays - 将数组向上移动一个级别,但即使为空也保留数组
- swift - 删除视图中的绑定对象时出现“致命错误:索引超出范围”
- html - 如何分离页眉正文和页脚
- python - 随机森林分类器+词袋导致大小问题
- r - 将一列中的信息传播到R中的多个
- json - 如何将 JSON 与不同的顺序进行比较?