急!父子进程中命名管道通讯异常

Joan201401 2013-07-29 05:26:08
我想实现这样的功能:
父进程负责启动和管理子进程(10个子进程),当子进程未连上服务器端时,子进程退出,下次父进程重新创建子进程;当子进程对应的服务器端断开连接时,子进程也退出,父进程重新创建子进程。
代码如下:

// 父进程
while(1)
{
int iConnectFlag[10]; // 子进程的状态,0:未启动,1:启动并工作正常
pid_t pid[10];
char buffer[20];
memset( iConnectFlag,0,10*sizeof(int));
for( int i=0; i < 10; i++)
{

if( iConnectFlag[i] == 0 )
{
pid[i] = fork();
if(pid[iChannelIdx] < 0) // error, return
{
printf("fork error\n ");
}
else if (pid[i] == 0) // the child process
{
int re = connectserver(); // 连接服务器,
if(re==0)//连接成功
{
int pipe_fd;
int open_mode = O_WRONLY;
pipe_fd = open(FIFO_NAME,open_mode);
if(pipe_fd != -1)
{
sprintf(buffer,"%.2xstart", i);
int res=write(pipe_fd,Buffer,BUFFER_SIZE);
if(res==-1)
{
fprintf(stderr,"write error on pipe\n");
exit(0);
}
else
{
printf("write ok,buffer=%s\n",pchBuffer);
}
}

close(pipe_fd);

work();// 里面有while循环,一直工作,直到和服务器断开连接
sprintf(buffer,"%.2xstop!", i);
WriteToPipe( buffer);

sleep(3);
exit(0); // 子进程退出
}
else
{
int pipe_fd;
int open_mode = O_WRONLY;
pipe_fd = open(FIFO_NAME,open_mode);
if(pipe_fd != -1)
{
sprintf(buffer,"%.2xstop", i);
int res=write(pipe_fd,Buffer,BUFFER_SIZE);
if(res==-1)
{
fprintf(stderr,"write error on pipe\n");
exit(0);
}
else
{
printf("write ok,buffer=%s\n",pchBuffer);
}
}

close(pipe_fd);
sleep(3);
exit(0); // 子进程退出
}
}
else // in parent
{
}
}
else
{
int pipe_fd;
int open_mode = O_WRONLY;
pipe_fd = open(FIFO_NAME,open_mode);
if(pipe_fd != -1)
{
sprintf(buffer,"%.2xtest", i);
int res=write(pipe_fd,Buffer,BUFFER_SIZE);
if(res==-1)
{
fprintf(stderr,"write error on pipe\n");
exit(0);
}
else
{
printf("write ok,buffer=%s\n",pchBuffer);
}
}

close(pipe_fd);
sleep(1);
}

sleep(1);

int pipe_fd;
int open_mode = O_RDONLY;
char buffer[BUFFER_SIZE+1];

if(access(FIFO_NAME,0777)==-1)
{
pipe_fd = open(FIFO_NAME,open_mode);
if(pipe_fd != -1)
{
res=read(pipe_fd,buffer,BUFFER_SIZE);
if(res==-1)
{
fprintf(stderr,"read error on pipe\n");
}
else
{
printf("read ok,buffer=%s\n",buffer);

string strCommand;
char chCommand[20];
int iChannelNum;

// 解析FIFO字符串内容
ParsePipeContent(buffer, iNum, chCommand );
strCommand.insert(0,chCommand);


if(strCommand=="start") // this channel has been started.
{
iConnectFlag[iNum] =1;
}
else if(strCommand=="stop!") // this channel has been stoped.
{
iConnectFlag[iNum] = 0;
}

}

close(pipe_fd);
}
}
}
}

程序刚运行的时候,各个子进程可以连接服务器,但是当子进程和服务器连接断开后,父进程就不会创建新的子进程了,因为命名管道通讯的问题。纠结,不知道怎么回事,请高手帮忙看看,谢谢了!
...全文
132 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Joan201401 2013-08-13
  • 打赏
  • 举报
回复
问题没有完全解决,结贴收工。
Joan201401 2013-07-30
  • 打赏
  • 举报
回复
重新贴一下代码:
// 父进程
while(1)
{	
	int iConnectFlag[10]; // 子进程的状态,0:未启动,1:启动并工作正常
	pid_t pid[10];
	char buffer[20];
	memset(	iConnectFlag,0,10*sizeof(int));
	for( int i=0; i < 10; i++)
	{

		if( iConnectFlag[i] == 0  )
		{
			pid[i] = fork();
			if(pid[iChannelIdx] < 0)  // error, return
			{
				printf("fork error\n ");
			}
			else if (pid[i] == 0) // the child process
			{
				int re = connectserver(); // 连接服务器,
				if(re==0)//连接成功
				{
					int pipe_fd;
					int open_mode = O_WRONLY;
					pipe_fd = open(FIFO_NAME,open_mode);
					if(pipe_fd != -1)
					{
						sprintf(buffer,"%.2xstart", i);
						int res=write(pipe_fd,Buffer,BUFFER_SIZE);
						if(res==-1)
						{
							fprintf(stderr,"write error on pipe\n");
							exit(0);
						}
						else
						{
							printf("write ok,buffer=%s\n",pchBuffer);
						}
					}
					
					close(pipe_fd);

					work();// 里面有while循环,一直工作,直到和服务器断开连接
					sprintf(buffer,"%.2xstop!", i);
					WriteToPipe( buffer);

					sleep(3);
					exit(0);  // 子进程退出
				}
				else
				{
					int pipe_fd;
					int open_mode = O_WRONLY;
					pipe_fd = open(FIFO_NAME,open_mode);
					if(pipe_fd != -1)
					{
						sprintf(buffer,"%.2xstop", i);
						int res=write(pipe_fd,Buffer,BUFFER_SIZE);
						if(res==-1)
						{
							fprintf(stderr,"write error on pipe\n");
							exit(0);
						}
						else
						{
							printf("write ok,buffer=%s\n",pchBuffer);
						}
					}
					
					close(pipe_fd);
					sleep(3);
					exit(0); // 子进程退出
				}
			}
			else // in parent
			{
			}
		}
		else
		{
			int pipe_fd;
			int open_mode = O_WRONLY;
			pipe_fd = open(FIFO_NAME,open_mode);
			if(pipe_fd != -1)
			{
				sprintf(buffer,"%.2xtest", i);
				int res=write(pipe_fd,Buffer,BUFFER_SIZE);
				if(res==-1)
				{
					fprintf(stderr,"write error on pipe\n");
					exit(0);
				}
				else
				{
					printf("write ok,buffer=%s\n",pchBuffer);
				}
			}
					
			close(pipe_fd);
			sleep(1);
		}

		sleep(1);

		int pipe_fd;
		int open_mode = O_RDONLY;
		char buffer[BUFFER_SIZE+1];

		if(access(FIFO_NAME,0777)==-1)
		{
			pipe_fd = open(FIFO_NAME,open_mode);
			if(pipe_fd != -1)
			{
				res=read(pipe_fd,buffer,BUFFER_SIZE);
				if(res==-1)
				{
					fprintf(stderr,"read error on pipe\n");
				}
				else
				{
					printf("read ok,buffer=%s\n",buffer);

					string strCommand;
					char chCommand[20];
					int iChannelNum;

					// 解析FIFO字符串内容
					ParsePipeContent(buffer, iNum, chCommand );
					strCommand.insert(0,chCommand);

	
					if(strCommand=="start") // this channel has been started.
					{
						iConnectFlag[iNum] =1;
					}
					else if(strCommand=="stop!") // this channel has been stoped.
					{
						iConnectFlag[iNum] = 0;
					}
			
				}

				close(pipe_fd);
			}
		}
	}
}
Joan201401 2013-07-30
  • 打赏
  • 举报
回复
就是,执行write的时候会阻塞,怎么解决呢?
Joan201401 2013-07-30
  • 打赏
  • 举报
回复
to :qq120848369 我把读改成了非阻塞,这样阻塞的问题解决了。 但是又出现了新的问题,当子进程和服务器建立连接后,通过WriteToPipe()写管道跟父进程通讯,来改变连接标识。父进程读到如果是已连接标识,那么就不在创建对应的子进程。问题就是,有可能在写之前,已经轮到父进程读标识了,此时去读,“未连接”的标识尚未改变,父进程则会再次创建子进程,这样就有了2个子进程了,多了一个多余的子进程。
Joan201401 2013-07-30
  • 打赏
  • 举报
回复
to erhou134: WriteToPipe()这个函数每次会打开描述符,然后写完就关了。
qq120848369 2013-07-30
  • 打赏
  • 举报
回复
写pipe阻塞很正常啊,满了就阻塞了,你可以设置非阻塞,然后应用层缓冲待写数据。
空的 2013-07-30
  • 打赏
  • 举报
回复
close(pipe_fd); work();// 里面有while循环,一直工作,直到和服务器断开连接 sprintf(buffer,"%.2xstop!", i); WriteToPipe( buffer); 这里是不是把 描述符关了,然后又往里写?
justkk 2013-07-29
  • 打赏
  • 举报
回复
代码贴的也太乱了吧

跟踪一下,是不是哪儿阻塞了?

23,124

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧