2015-10-14 100 views
0

我正在嘗試在C中開發電梯模擬器應用程序,因此我即將使用共享內存和管道進行內部數據庫通信。 爲了讓我的生活更輕鬆一點,我宣佈了兩個函數read_from_pipewrite_to_pipe不能讓'孩子'和'父母'一起正確通信

下面是我main代碼的一部分,我需要找出原因預期不會表現:

01 #include <stdio.h> 
02 #include <stdlib.h> 
03 #include <string.h> 
04 #include <sys/types.h> 
05 #include <sys/stat.h> 
06 #include <fcntl.h> 
07 #include <sys/mman.h> 
08 
09 #include "windows.h" 
10 
11 #define READ 0 
12 #define WRITE 1 
13 
14 typedef struct lift 
15 { 
16   int winch_control; 
17   int door_control; 
18   int call_buttons; 
19   int lift_buttons; 
20   double position; 
21   double door_ajar; 
22   int quit; 
23   int reset; 
24   int error; 
25 } lift; 
26 int main(void) 
27 { 
28 lift *pLift; 
29 pid_t pid; 
30 off_t off = 0; 
31 int liftfd, mmlen = sizeof(lift), FIFO[2];; 
32 
33 pid = fork(); 
34 liftfd = open("liftfile", (O_CREAT | O_RDWR), 0666); 
35 pLift = (lift *)mmap((caddr_t)0, mmlen, (PROT_READ | PROT_WRITE), MAP_SHARED, liftfd, off); 
36 
37 if (pipe(FIFO))     // create pipe failed 
38 { 
39  fprintf(stderr, "Pipe failed.\n"); 
40  return EXIT_FAILURE; 
41 } 
42 
43 if (pid == (pid_t)0)   // child process 
44 { 
45  close(FIFO[WRITE]);   
46  read_from_pipe(FIFO[READ]); 
47  close(FIFO[READ]); 
48 } 
49 else if (pid < (pid_t)0)  // create fork failed 
50 { 
51  fprintf(stderr, "Fork failed.\n"); 
52  return EXIT_FAILURE; 
53 } 
54 else       // parent process 
55 { 
56  close(FIFO[READ]);   
57  write_to_pipe(FIFO[WRITE],"UP3" , 56); 
58  close(FIFO[WRITE]); 
59 } 
60 } 

read_from_pipe子程序:

void read_from_pipe(int fileDescriptr) 
{ 
    FILE *stream; 
    int c; 
    stream = fdopen(fileDescriptr, "r"); 
    while ((c = fgetc(stream)) != EOF) 
     putchar(c); 
    fclose(stream); 
} 

write_to_pipe子程序:

void write_to_pipe(int fileDescriptr , char *stateName , int timerValue) 
{ 
    FILE *stream; 
    stream = fdopen(fileDescriptr, "w"); 
    fprintf(stream, "Current system state:\t%s\n", stateName); 
    fprintf(stream, "Timer value:\t\t%d\n",timerValue); 
    fflush(stream); 
    fclose(stream); 
} 

夫妻倆我窩我想指出:

  • 如果有人想要參考特定的 行,我會提供行號。我假設每個人都知道如何在代碼 編輯器中使用列模式,並將其全部刪除,以便編譯成功。
  • 代碼中的許多內容可能看起來多餘,但實際上它們正在代碼中的其他地方使用。因此,如果您選擇了任何一項,請忽略 冗餘。
  • 我在Windows上使用CygWin。

根據行號57,我的預期結果是:

Current system state:  UP3 
Timer value:    56 

不過,我得到一個空白屏幕。

任何想法我做錯了什麼?

回答

1

調用fork()後有3個possiblities

1)的返回值是< 0,表示該叉()失敗

2)返回的值爲0,表示子正在執行

3)返回的值大於0表示父節點正在執行。

假設沒有發生故障,則父母和孩子在撥打fork()後執行該代碼。所以父母和孩子都撥打open()mmap()

需要檢查open()和mmap()的返回值,以確保操作成功。

mmap()結果未在發佈的代碼中使用。

open()結果未在發佈的代碼中使用。

該行:fprintf(stderr, "Fork failed.\n");應該可能是對perror()的調用,因此係統錯誤消息也會顯示。

問題的根源似乎是一種競爭條件。

建議使用read()而不是fgetc()作爲讀取將等待所需數量的字符,因此將等待傳遞的數據可用。一定要檢查從read()返回的值,然後再試一次,直到返回值爲0(或小於0的錯誤)

+0

您是對的。我在'pipe()'調用後將所有內容放入'else'語句中,並且工作正常! – Bababarghi