写入的字节数始终为 -1
Number of bytes written is always -1
我正在尝试实现一些没有互斥体、条件和信号量的 IPC,仅使用管道。
以下代码表示一个 parent 进程在 3 child 秒内分叉 (p11,p12,p13)
parent 用 SIGUSR2
信号唤醒所有 childs,然后 p11 开始向管道写入 50 个随机数。 p12 和 p13 竞争性地从管道中读取并将获得的数字写入自己的文件(file12 和 file13)。第 50 个数字是 -1
,一旦 child 读到 -1,它们就退出。
p11child中使用的write
,就是不写一个字节,它returns-1
我只能使用 write(2)
和 read(2)
调用来进行写入和读取。
我好像无法实现,试了好几次都没有结果。希望你能帮助我。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/wait.h>
void handler(int signo)
{
printf("\nSignal intercepted!\n");
}
void main ()
{
srand(time(NULL));
signal(SIGUSR2,handler);
int pa[2];
pipe(pa[2]); //create pipe
pid_t pid1,pid2,pid3;
if((pid1=fork())==0) //child 11
{
close(pa[0]); //close the read side of the pipe
pause();
int i,nwrite,num;
for(i=0;i<49;i++)
{
num=rand()%100+1; //generate a random number
nwrite=write(pa[1],&num,sizeof(int)); //write it to the pipe
if(nwrite==-1) //if there's a write error
{
printf("\nWrite error..\n");
exit(-1);
}
}
num=-1; //generate the last number
nwrite=(write(pa[1],&num,sizeof(int))); //write the last number to the pipe
if (nwrite==-1) //if there's a write error
{
printf("\nError,now exiting...\n");
exit(-1);
}
close(pa[1]); //close the pipe in write mode
exit(1);
}
else if ((pid2=fork())==0) //child 12
{
close(pa[1]); //close the write side of the pipe
pause();
int fd1,nread,num;
fd1=open("file12.txt",O_CREAT,0777); //create a new file
while((nread=read(pa[0],&num,sizeof(num)))>0) //while there are bytes to read
{
if(num!=-1) //if this isn't the last number
{
write(fd1,&num,sizeof(num)); //write it to the file
}
else
{
printf("\n-1 sent!\n"); //notify the last read number
close(pa[0]); //close the read side of the pipe
close(fd1); //close the file descriptor
exit(1); //exit
}
}
}
else if ((pid3=fork())==0) //child 13, same as 12
{
close(pa[1]);
pause();
int fd2,nread,num;
fd2=open("file13.txt",O_CREAT,0777);
while((nread=read(pa[0],&num,sizeof(num)))>0)
{
if(num!=-1)
{
write(fd2,&num,sizeof(num));
}
else
{
printf("\n-1 sent!\n");
close(pa[0]);
close(fd2);
exit(1);
}
}
}
else //parent
{
sleep(1);
kill(pid1,SIGUSR2); //wake up all the childs
kill(pid2,SIGUSR2);
kill(pid3,SIGUSR2);
waitpid(pid1,0,NULL); //wait for the childs to end
waitpid(pid2,0,NULL);
waitpid(pid3,0,NULL);
printf("\nDone, now exiting...\n"); //exit
}
}
至少这个*1
int pa[2];
pipe(pa[2]);
应该是
int pa[2];
pipe(pa);
背景:
pa[2]
的计算结果为 int
。另一方面,pipe()
需要 int[2]
,在定义函数参数的上下文中,它与 int[]
相同,而 int[]
与 int *
相同。
如果一个数组被传递给一个函数,它会衰减到一个指针它的第一个元素。因此将 pa
传递给 pipe()
将导致传递 &pa[0]
,这确实是一个 int *
.
*1
顺便说一句,编码 pa[2]
在任何情况下都会引发未定义的行为,因为它只读出 pa
的 3rd 元素,只有 pa
有两个元素。
我正在尝试实现一些没有互斥体、条件和信号量的 IPC,仅使用管道。
以下代码表示一个 parent 进程在 3 child 秒内分叉 (p11,p12,p13)
parent 用 SIGUSR2
信号唤醒所有 childs,然后 p11 开始向管道写入 50 个随机数。 p12 和 p13 竞争性地从管道中读取并将获得的数字写入自己的文件(file12 和 file13)。第 50 个数字是 -1
,一旦 child 读到 -1,它们就退出。
p11child中使用的write
,就是不写一个字节,它returns-1
我只能使用 write(2)
和 read(2)
调用来进行写入和读取。
我好像无法实现,试了好几次都没有结果。希望你能帮助我。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/wait.h>
void handler(int signo)
{
printf("\nSignal intercepted!\n");
}
void main ()
{
srand(time(NULL));
signal(SIGUSR2,handler);
int pa[2];
pipe(pa[2]); //create pipe
pid_t pid1,pid2,pid3;
if((pid1=fork())==0) //child 11
{
close(pa[0]); //close the read side of the pipe
pause();
int i,nwrite,num;
for(i=0;i<49;i++)
{
num=rand()%100+1; //generate a random number
nwrite=write(pa[1],&num,sizeof(int)); //write it to the pipe
if(nwrite==-1) //if there's a write error
{
printf("\nWrite error..\n");
exit(-1);
}
}
num=-1; //generate the last number
nwrite=(write(pa[1],&num,sizeof(int))); //write the last number to the pipe
if (nwrite==-1) //if there's a write error
{
printf("\nError,now exiting...\n");
exit(-1);
}
close(pa[1]); //close the pipe in write mode
exit(1);
}
else if ((pid2=fork())==0) //child 12
{
close(pa[1]); //close the write side of the pipe
pause();
int fd1,nread,num;
fd1=open("file12.txt",O_CREAT,0777); //create a new file
while((nread=read(pa[0],&num,sizeof(num)))>0) //while there are bytes to read
{
if(num!=-1) //if this isn't the last number
{
write(fd1,&num,sizeof(num)); //write it to the file
}
else
{
printf("\n-1 sent!\n"); //notify the last read number
close(pa[0]); //close the read side of the pipe
close(fd1); //close the file descriptor
exit(1); //exit
}
}
}
else if ((pid3=fork())==0) //child 13, same as 12
{
close(pa[1]);
pause();
int fd2,nread,num;
fd2=open("file13.txt",O_CREAT,0777);
while((nread=read(pa[0],&num,sizeof(num)))>0)
{
if(num!=-1)
{
write(fd2,&num,sizeof(num));
}
else
{
printf("\n-1 sent!\n");
close(pa[0]);
close(fd2);
exit(1);
}
}
}
else //parent
{
sleep(1);
kill(pid1,SIGUSR2); //wake up all the childs
kill(pid2,SIGUSR2);
kill(pid3,SIGUSR2);
waitpid(pid1,0,NULL); //wait for the childs to end
waitpid(pid2,0,NULL);
waitpid(pid3,0,NULL);
printf("\nDone, now exiting...\n"); //exit
}
}
至少这个*1
int pa[2];
pipe(pa[2]);
应该是
int pa[2];
pipe(pa);
背景:
pa[2]
的计算结果为 int
。另一方面,pipe()
需要 int[2]
,在定义函数参数的上下文中,它与 int[]
相同,而 int[]
与 int *
相同。
如果一个数组被传递给一个函数,它会衰减到一个指针它的第一个元素。因此将 pa
传递给 pipe()
将导致传递 &pa[0]
,这确实是一个 int *
.
*1
顺便说一句,编码 pa[2]
在任何情况下都会引发未定义的行为,因为它只读出 pa
的 3rd 元素,只有 pa
有两个元素。