信号量和父子进程
Semaphore and father son process
我有这段代码创建了一个进程和他的儿子,他们每个人都会在他的代码中创建一个“for 循环”,它将从 a 到 z 和从 A 到 Z 写入一个文件;仅使用一个信号量,创建的文件仅包含从“A”到“Z”的大写字母和一个“a”,这意味着只有父亲完成了他的循环,而儿子仅 运行 一次。
通过使用两个信号量,我设法 运行 代码就像我想要的那样 AaBbCcDdEeFf...Zz
所以我的问题是关于以下代码(带有一个信号量),为什么儿子没有完成他的循环?
感谢您的帮助
编辑:clef = 代码中的键
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<unistd.h>
#include<stdio.h>
main()
{
int pid_P2,clef,sema;
char i;
ushort tab_sema[1];
struct sembuf operation [1];
FILE *p ;
p=fopen("file.txt","w");
if (p==NULL)
{
perror("Error opening file");
exit(0);
}
clef=ftok("file.txt",8);
operation[0].sem_num=0;
operation[0].sem_flg=0;
pid_P2=fork();
sema=semget(clef,1,IPC_CREAT|0600);
if (sema==-1) { perror("pb semget");
exit(0); }
semctl(sema,0,SETVAL,1);
if (pid_P2==0)
{ /* Son's Code */
for (i='a';i<'z'+1;i++)
{
operation[0].sem_op=-1;
semop(sema,operation,1);
fprintf(p,"%c",i);
fflush(p);
operation[0].sem_op=+1;
semop(sema,operation,1);
}
exit(0);
}
else{ /* Father's Code */
for (i='A';i<'Z'+1;i++)
{
operation[0].sem_op=-1;
semop(sema,operation,1);
fprintf(p,"%c",i);
fflush(p);
operation[0].sem_op=+1;
semop(sema,operation,1);
}
sleep(2);
exit(0);
}
fclose(p);
}
我测试了你的代码并且我有
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
因此我无法重现您的问题。
然而在我看来你的问题来自于你的父进程没有等待其 child 完成的事实:你应该用 waitpid(pid_P2, NULL, 0)
替换 sleep(2)
来制作确保在 child 完成其工作之前没有退出。
就是说,您的信号量似乎更像是一个互斥锁而不是信号信号量,因此父亲和 child 之间存在文件访问竞争。似乎父亲总是在你的案子中获胜,并在儿子有时间写超过 'a' 之前退出。因此,我认为您将无法使用单个信号量实现 AaBbCcDdEeFf...Zz 目标。
我有这段代码创建了一个进程和他的儿子,他们每个人都会在他的代码中创建一个“for 循环”,它将从 a 到 z 和从 A 到 Z 写入一个文件;仅使用一个信号量,创建的文件仅包含从“A”到“Z”的大写字母和一个“a”,这意味着只有父亲完成了他的循环,而儿子仅 运行 一次。
通过使用两个信号量,我设法 运行 代码就像我想要的那样 AaBbCcDdEeFf...Zz
所以我的问题是关于以下代码(带有一个信号量),为什么儿子没有完成他的循环?
感谢您的帮助
编辑:clef = 代码中的键
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<unistd.h>
#include<stdio.h>
main()
{
int pid_P2,clef,sema;
char i;
ushort tab_sema[1];
struct sembuf operation [1];
FILE *p ;
p=fopen("file.txt","w");
if (p==NULL)
{
perror("Error opening file");
exit(0);
}
clef=ftok("file.txt",8);
operation[0].sem_num=0;
operation[0].sem_flg=0;
pid_P2=fork();
sema=semget(clef,1,IPC_CREAT|0600);
if (sema==-1) { perror("pb semget");
exit(0); }
semctl(sema,0,SETVAL,1);
if (pid_P2==0)
{ /* Son's Code */
for (i='a';i<'z'+1;i++)
{
operation[0].sem_op=-1;
semop(sema,operation,1);
fprintf(p,"%c",i);
fflush(p);
operation[0].sem_op=+1;
semop(sema,operation,1);
}
exit(0);
}
else{ /* Father's Code */
for (i='A';i<'Z'+1;i++)
{
operation[0].sem_op=-1;
semop(sema,operation,1);
fprintf(p,"%c",i);
fflush(p);
operation[0].sem_op=+1;
semop(sema,operation,1);
}
sleep(2);
exit(0);
}
fclose(p);
}
我测试了你的代码并且我有
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
因此我无法重现您的问题。
然而在我看来你的问题来自于你的父进程没有等待其 child 完成的事实:你应该用 waitpid(pid_P2, NULL, 0)
替换 sleep(2)
来制作确保在 child 完成其工作之前没有退出。
就是说,您的信号量似乎更像是一个互斥锁而不是信号信号量,因此父亲和 child 之间存在文件访问竞争。似乎父亲总是在你的案子中获胜,并在儿子有时间写超过 'a' 之前退出。因此,我认为您将无法使用单个信号量实现 AaBbCcDdEeFf...Zz 目标。