2017-04-15 30 views
0

我對管道有用戶讀/寫權限。小組已閱讀。其他已閱讀。但是當我運行它時,程序會「卡住」。計劃1是「父母」。計劃2是「孩子」。命名管道將不會在C程序中打開

計劃1:

int main(int argc, char * argv[]) 
{ 
FILE *fptr; //for opening and closing input file 
int fdw;// write to pipe; 
int fdr; //read to pipe; 
pid_t pid; 
int inputarray[500]; 
int arraylength = 0; int j =0; 
char *mypipe = "mypipe"; 


if (argc < 2) 
{ 
    printf("Need to provide the file's name. \n"); 
    return EXIT_FAILURE; 
} 
//open input file 
fptr = fopen(argv[1], "r"); 
if (fptr==NULL) 
{ 
    printf("fopen fail.\n"); 
    return EXIT_FAILURE; 
} 

//read input file and fill array with integers 
while (!feof(fptr)) 
{ 
    fscanf(fptr,"%d",&inputarray[arraylength]); 
    arraylength = arraylength + 1; 

} 

fclose(fptr); //close input file 



pid = fork(); 

mkfifo(mypipe, 0666); 
fdw = open("mypipe",O_WRONLY); 
if (fdw < 0) 
{ 
    perror("File can't open to write."); 
    return; 
} 
int b; 
b=3; 
write(fdw,&b,sizeof(b)); 
close(fdw); 




if (pid ==-1) 
{ 
perror("fork"); 
exit(1); 
} 
int status; //exit status of child 

if(pid==0)//if child process 
{ 
    execl("program2", (char*) NULL); 
} 

else //if parent process 
{ 
wait(&status);} 
if((WIFEXITED(status))) 
{ 
printf("Child's exit code %d", WEXITSTATUS(status)); 
} 
else{ 
printf("Child did not terminate with exit");} 



} 

方案2:

int fdl; 
int data; 
fdl = open("mypipe",O_RDONLY); 
if (fdl < 0) 
{ 
    perror("File can't open to read."); 
    return; 
} 
read(fdl,&data,sizeof(data)); 
close(fdl); 
+0

哪個程序卡住了? – thrig

+0

程序1卡住了。這是父母。計劃2是孩子。 – Alex

+0

您是否知道您可以在一個程序中完成所有操作:程序1中的exec可以替換爲program2的內容。 –

回答

1

節目將寫入FIFO,直到它的寫作正在讀取塊。由於execl()直到的寫作都不會發生子過程中的讀數。

此外,它看起來像兩個過程實際上將嘗試寫入FIFO中,因爲你fork(),然後立即開始寫作。

你應該fork(),然後在返回的PID測試。家長應該寫信給fifo,而孩子應該撥打execl()。該fifo應由fork()調用之前的父級創建。

您還應該考慮使用indentclang-format正確地設置代碼的格式,這樣可以輕鬆讀取代碼,並可能會暴露錯誤(忘記花括號等)。


一個簡單的完整示例程序。父字符串寫入孩子和孩子的性格讀取它的性格和它輸出到標準輸出:

#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/stat.h> 
#include <sys/wait.h> 
#include <unistd.h> 

void parent(void); 
void child(void); 

int main(void) { 
    pid_t pid; 

    mkfifo("myfifo", 0666); /* fails if exists, but we don't care here */ 

    if ((pid = fork()) < 0) 
    abort(); 

    if (pid == 0) 
    child(); /* will not return */ 
    else 
    parent(); 

    return EXIT_SUCCESS; 
} 

void parent(void) { 
    int fd; 
    int len; 
    int ret; 
    int stat; 

    char *ptr; 
    char *msg = "Hello World!"; 

    if ((fd = open("myfifo", O_WRONLY)) < 0) 
    abort(); 

    len = strlen(msg) + 1; 
    ptr = msg; 

    puts("Parent: About to write to child"); 

    while ((ret = write(fd, ptr, len)) != 0) { 
    if (ret > 0) { 
     len -= ret; 
     ptr += ret; 
    } else 
     abort(); 
    } 

    close(fd); 

    puts("Parent: Waiting for child to exit"); 
    wait(&stat); 

    printf("Parent: Child exited with status %d\n", stat); 
} 

void child(void) { 
    int fd; 
    int ret; 

    char ch; 

    if ((fd = open("myfifo", O_RDONLY)) < 0) 
    abort(); 

    puts("Child: About to read from parent"); 

    while ((ret = read(fd, &ch, 1)) != 0) { 
    if (ret > 0) 
     putchar(ch); 
    else 
     abort(); 
    } 
    putchar('\n'); 

    close(fd); 

    puts("Child: I'm done here"); 
    exit(EXIT_SUCCESS); 
} 

在這種情況下,因爲這兩個孩子,父進程都在同樣的情況下,我可以用用pipe()創建的匿名管道對,但是這說明了流程,包括創建命名管道。

+0

所以家長應寫信給等待呼叫之後或之前的管道? – Alex

+0

@Alex之前。當孩子退出時,wait()會返回。 'write()'將會阻塞,直到子'read()'它。 – Kusalananda

+0

我在fork()之前創建了pipe並且write()在wait()之後但仍然卡住。 – Alex