我有这个代码: 当第一个孩子向第二个孩子发送数据时程序卡住, 第二个孩子做了fscanf然后卡住了因为他无法读到我找不到它的原因。 请帮助我找出如何确保fflush将传输数据。
int main()
{
pid_t childPid ; //Child's and father process id.
int i ; //An index to create children in loop.
unsigned int st_search_prime = 0 ;
if((mkfifo(FIRST_FIFO, S_IFIFO | 0644) == FAIL && errno != EEXIST) ||
(mkfifo(SECOND_FIFO, S_IFIFO | 0644) == FAIL && errno != EEXIST))
{
perror("Cannot create fifo file") ;
exit(EXIT_FAILURE) ;
}
//create the children
for(i = 0 ; i < NUM_OF_CHILDS ; i++)
{
childPid = fork() ;
if(childPid < 0) //Fork failed.
{
perror("Cannot fork()") ;
exit(EXIT_FAILURE) ;
}
else if(childPid == CHILD) //child process
{
if(i == FIRST_SON) //the 1st child process
doChild1(st_search_prime) ;
else //the 2nd child process.
doChild2(st_search_prime) ;
}
}
//wait for the children to exit.
for(i = 0 ; i < NUM_OF_CHILDS ; i++)
wait(&childPid) ;
return(EXIT_SUCCESS) ;
}
void doChild1(unsigned int st_search_prime)
{
int counter = 0 ; //Counter for N successfully raffle .
FILE* fdw1 ;
FILE* fdr2 ;
if((!(fdw1 = fopen(FIRST_FIFO, "w"))))
{
perror("Cannot open fifo file for w/r") ;
exit(EXIT_FAILURE) ;
}
if((!(fdr2 = fopen(SECOND_FIFO, "r"))))
{
perror("Cannot open fifo file for w/r") ;
exit(EXIT_FAILURE) ;
}
for(; counter < N ; counter++)
{
st_search_prime = raffle_prime(st_search_prime) ;
**fprintf(fdw1, "%u\n", st_search_prime) ;
fflush(fdw1) ;**
printf("%u\n", st_search_prime) ;
fscanf(fdr2, "%u\n", &st_search_prime) ;
}
fclose(fdw1) ;
fclose(fdr2) ;
exit(EXIT_SUCCESS) ;
}
void doChild2(unsigned int st_search_prime)
{
int counter = 0 ; //Counter for N successfully raffle .
FILE* fdw2 ;
FILE* fdr1 ;
if((!(fdr1 = fopen(FIRST_FIFO, "r"))))
{
perror("Cannot open fifo file for w/r") ;
exit(EXIT_FAILURE) ;
}
if(!(fdw2 = fopen(SECOND_FIFO, "w")))
{
perror("Cannot open fifo file for w/r") ;
exit(EXIT_FAILURE) ;
}
for(; counter < N ; counter++)
{
**fscanf(fdr1, "%u\n", &st_search_prime);**
st_search_prime = raffle_prime(st_search_prime) ;
fprintf(fdw2, "%u\n", st_search_prime) ;
fflush(fdw2) ;
printf("%u\n", st_search_prime) ;
}
fclose(fdr1) ;
fclose(fdw2) ;
exit(EXIT_SUCCESS) ;
}
答案 0 :(得分:0)
尝试添加致电setlinebuf(fdw1)
- 这应该会有所帮助。
此换算在换行后强制刷新缓冲区。您也可以使用参数setvbuf()
的{{1}}来获得相同的效果,或者使用_IOLBF
来完全禁用缓冲。
答案 1 :(得分:0)
我认为问题在于\n
模式中使用fscanf
。 fscanf
的手册页说:
格式字符串由一系列指令组成 描述如何处理输入字符序列。如果 指令的处理失败,没有读取进一步的输入,和 scanf()返回。 A&#34;失败&#34;可以是以下任何一种: 输入失败,意味着输入字符不可用,或 匹配失败,意味着输入不合适......
此外,根据指示,我们有:
一系列空格字符(空格,制表符,换行符等;请参阅 isspace为(3))。该指令匹配任意数量的空白区域, 包括无,在输入中。
因此,当在doChild2
中使用fscanf
模式"%u\n"
时,模式由两个输入指令组成,%u
与传入的数字匹配,然后{{ 1}}匹配传入的换行符(空格)。此时\n
将继续寻找更多输入,因为不再发送输入会导致程序阻塞。
为什么fscanf
会回去寻找更多输入?上面的第一个引用告诉我们终止的两个条件,或者没有更多的输入;好了,fifo仍然是开放的,所以我们不知道更多的输入不在路上,所以不满足条件,或者,如果指令不匹配,fscanf
将返回;但那还没有发生。
就修复而言,从fscanf
模式中删除\n
就足够了。手册页告诉我们:
大多数转化会丢弃初始空格字符......
fscanf
就属于这种情况,因此,如果您使用%u
但%u\n
的模式发送的模式为fscanf
,那么%u
将导致\n
指令失败,导致%u
返回。这会将fscanf
留在输入缓冲区中,但是,对\n
的下一次调用将丢弃初始空格(换行符),并且一切都应该正常。