我试图用 c 语言创建一个程序,它有一个父进程和三个子进程。目的是父级将通过两个管道与每个子级连接,因此当子级选择向其兄弟姐妹之一发送消息时,他们将首先将其发送给父级,然后将其发送给适当的子级。父级的读取端必须是非阻塞的。
我尝试遵循 https://www.geeksforgeeks.org/non-blocking-io-with-pipes-in-c/ 站点中的示例。我遇到的两个错误如下:
array type has incomplete element type 'int[]' void parent_read(int pipes[][]) (line 11)
type of formal parameter is incomplete parent_read(pipes); (line140)
我可以做什么来解决这个问题?到目前为止我在非阻塞方面所做的是否正确? 谢谢
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <time.h>
#define MSGSIZE 5
void parent_read(int pipes[][])
{
int nread;
char buf[MSGSIZE];
// write link
close(pipes[1]);
while (1) {
// read call if return -1 then pipe is
// empty because of fcntl
nread = read(pipes[0], buf, MSGSIZE);
switch (nread) {
case -1:
// case -1 means pipe is empty and errono
// set EAGAIN
if (errno == EAGAIN) {
printf("(pipe empty)\n");
sleep(1);
break;
}
else {
perror("read");
exit(4);
}
// case 0 means all bytes are read and EOF(end of conv.)
case 0:
printf("End of conversation\n");
// read link
close(pipes[0]);
exit(0);
default:
// text read
// by default return no. of bytes
// which read call read at that time
printf("MSG = %s\n", buf);
}
}
}
int main()
{
int pids[3],id[3];
int pipes[6][2];
int i;
for (i=0;i<6;i++)
{
if (pipe(pipes[i])==-1)
{
printf("Error in pipe: %d\n",i);
return 0;
}
else
{
printf("Error in pipe:!\n");
}
}
if (fcntl(pipes[0][0], F_SETFL, O_NONBLOCK) < 0)
{
exit(2);
}
for(i=0;i<3;i++)
{
pids[i]=fork();
if(pids[i]==0)
{
id[i]=getpid();
//printf("ID:%d\n",id[i]);
break;
}
}
if (getpid()==id[0])
{
for (i=0;i<6;i++)
{
if (i>0 && i>1)
{
close(pipes[i][0]);
close(pipes[i][1]);
printf("Pipes of A have closed:%d\n",i);
}
}
/* char* x="hello";
if (write(pipes[1][1],&x,sizeof(int)) == -1)
{
printf("error in write");
}*/
return 0;
}
if (getpid()==id[1])
{
for (i=0;i<6;i++)
{
if ((i>2 && i>3) || (i<2 && i<3))
{
close(pipes[i][0]);
close(pipes[i][1]);
printf("Pipes of B have closed:%d\n",i);
}
}
return 0;
}
if (getpid()==id[2])
{
for (i=0;i<6;i++)
{
if (i<4 && i<5)
{
close(pipes[i][0]);
close(pipes[i][1]);
printf("Pipes of C have closed:%d\n",i);
}
}
return 0;
}
if(getpid()!=0)
{
// char y;
parent_read(pipes); //Here i try to call parent read
//read(pipes[1][0],&y,sizeof(int));
//printf("The child processe has given:%y",y);
for(i=0;i<=3;i++)
{
wait(NULL);
}
printf("PARENT:%d\n",getpid());
}
}
int x[][]
无效 C.
C17 6.7.6.2 数组声明符:
限制
/--/
元素类型不得为不完整或函数 类型
未指定大小的数组是不完整类型。因此,在
int x[][]
的情况下,它是一个不完整类型的数组,而该数组又具有一个也不完整的元素类型 int []
。所以这违反了上述语言限制。
那么为什么我们可以声明一个单一维度的函数参数
int x[]
呢?首先,这里的元素类型是int
,所以按照上面的规则就可以了。
接下来我们需要知道函数的数组参数被编译器隐式“调整”为指向第一个元素的指针(参见 C17 6.7.6.3)。这就像在表达式中使用数组时一样 - 它“衰减”为指向第一个元素的指针。
因此,如果我们声明
void func (int x[])
,即使我们没有指定数组大小也没关系。因为无论如何它都会调整为 int* x
,因此指定的数组大小并不重要。
还有一个要求,一旦调整完成,我们必须有一个“完整对象类型”的参数:
C17 6.7.6.3
调整后,作为该函数定义一部分的函数声明符中的参数类型列表中的参数不得具有不完整类型。
这也很好,因为我们有一个
int*
- 指针是一个完整的对象类型。