下面的代码仅优先于第一个 child 修改共享变量。如何删除此错误?
The code below gives preference to only it's first child to modify a shared variable. How to remove this bug?
我想捕获所有 child 进程对 parent 进程对共享变量所做的更改。
问题来了。
parent 进程创建这样的结构:
struct data
{
int pid;
int n;
char c;
};
它创建了 k 个进程,并且结构与它的所有 child 共享。变量 c
被初始化为 'n' 并且它作为一个标志。
Parent定期"wakes up"(来自"sleep")在随机时间(不超过2秒)后检查c的值,如果c是'y' 然后打印 n 的值(连同相应的 pid)并使 c 再次成为 'n'。
另一方面,每隔 child Pi,1≤ i ≤ k,在随机时间(不超过 2 秒)后定期 "wakes up"(从 "sleep") ) 检查 c 的值,如果 c 是 'n',则将一些随机值分配给 n,连同其进程 ID 一起分配给 pid,打印该值及其自己的进程 ID,并使 c 为 'y'.
如果程序执行被用户终止(通过按 Ctrl-C),parent 及其所有 children 应该终止并且分配的内存应该被释放。
代码如下:
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
很明显,它只捕获一个 child 进程所做的更改,不给其他 child 进程机会。如何消除这个错误?
如果需要任何其他信息,请在下方发表评论。
您打算让 parent 和 k children 争夺共享内存,但您只生成了一个 child 无论如何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 children 会踩到彼此的更新,并且它们也共享相同的 pseudo-random数列.
我想捕获所有 child 进程对 parent 进程对共享变量所做的更改。
问题来了。 parent 进程创建这样的结构:
struct data
{
int pid;
int n;
char c;
};
它创建了 k 个进程,并且结构与它的所有 child 共享。变量 c
被初始化为 'n' 并且它作为一个标志。
Parent定期"wakes up"(来自"sleep")在随机时间(不超过2秒)后检查c的值,如果c是'y' 然后打印 n 的值(连同相应的 pid)并使 c 再次成为 'n'。
另一方面,每隔 child Pi,1≤ i ≤ k,在随机时间(不超过 2 秒)后定期 "wakes up"(从 "sleep") ) 检查 c 的值,如果 c 是 'n',则将一些随机值分配给 n,连同其进程 ID 一起分配给 pid,打印该值及其自己的进程 ID,并使 c 为 'y'.
如果程序执行被用户终止(通过按 Ctrl-C),parent 及其所有 children 应该终止并且分配的内存应该被释放。
代码如下:
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
很明显,它只捕获一个 child 进程所做的更改,不给其他 child 进程机会。如何消除这个错误?
如果需要任何其他信息,请在下方发表评论。
您打算让 parent 和 k children 争夺共享内存,但您只生成了一个 child 无论如何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 children 会踩到彼此的更新,并且它们也共享相同的 pseudo-random数列.