2010-08-10 175 views
1
void turtle (int gtot) 
{ 
    int msg; 
    fcntl(gtot,F_SETFL,O_NONBLOCK); 
    read(gtot,&msg,4); 

    gotoxy(12, 21); printf("The value of buffer for turtle is %d",msg); 

    //react to god's message 
    xcoor += msg; 
    msg = 0; 
      sleep(sleep_time); 
} 

void god (int gtot) 
{ 
     char choice, sign; 
     int distance; 
     scanf("%c",&choice); 
     //choice = getchar(); 
     gotoxy(1,18); 
     printf("Enter the distance which should be moved"); 
     fflush(stdout); 
     gotoxy(50, 14); 
     scanf ("%d", &distance); 
     int newd = distance; 
     //printf ("The distance that is to be moved by %d", distance); 

     if (choice == 'h') 
     { 
      write(gtoh,&distance,4); 
     } 
     else if (choice == 't') 
     { 
      write(gtot,&newd,4); 
      gotoxy(12,23); 
          printf("I am writing %d as the number", distance); 
          fflush(stdout); 
     } 
     //printf("You chose %s", &choice); 
     sleep(sleep_time); 
    } 
    main(){ 
int gtot[2]; 
pipe (gtot); 
pid_turtle = fork(); 
if (pid_turtle == 0) 
    { 
     close (gtot[1]); 
     turtle (gtot[0]); 
    } 

pid_god = fork(); 
if (pid_god == 0) 
    { 
     close (gtot[0]); 
     god (gtot[1]); 
    } 
    } 

當我從管道從神功能寫入烏龜功能。我希望它在用戶沒有提供任何輸入時不會返回任何內容,而當用戶給出時則不會返回任何內容。但printf語句是打印輸出像從管道讀取錯誤

 The value of buffer for turtle is 0106368 
     The value of buffer for turtle is 05291328 

在我看來,這似乎是數字的內存地址。我在程序中犯的錯誤是什麼?

回答

3

有關程序的若干意見:

在功能turtle

  1. 你不初始化變量msg
  2. 您爲O_NONBLOCK設置了gtot文件描述符。
  3. 但是你不檢查返回值read

這是一個重要的問題。 read正在返回並且您正在打印未初始化的值msg

  • forkclose也貢獻的方式。您在fork之前關閉了gtot[1]--這是「上帝」過程。如果您選擇使用這種雙親過程方法的單親,則不要close文件處理,直到完成fork -ing。

  • 另外,看起來您至少打算使用turtle函數,可能還有god函數進行循環。正如所寫,你的烏龜功能將立即退出:它沒有循環,它執行read並設置了O_NONBLOCK標誌。

  • 但是等等,還有更多。當您撥打fcntl來設置O_NONBLOCK時,您所做的還將重置除O_NONBLOCK以外的每個標誌。

/*設置遞減的O_NONBLOCK標誌,如果值不爲零, 或清除標誌,如果值是:這裏是從the libc documentation其處理其它標誌而設置或復位非阻塞標誌截取的功能0. 成功時返回0,或者錯誤時使用errno set返回-1。*/

int 
set_nonblock_flag (int desc, int value) 
{ 
    int oldflags = fcntl (desc, F_GETFL, 0); 
    /* If reading the flags failed, return error indication now. */ 
    if (oldflags == -1) 
    return -1; 
    /* Set just the flag we want to set. */ 
    if (value != 0) 
    oldflags |= O_NONBLOCK; 
    else 
    oldflags &= ~O_NONBLOCK; 
    /* Store modified flag word in the descriptor. */ 
    return fcntl (desc, F_SETFL, oldflags); 
} 

有可能還可以促進你的問題的一些其他的東西:

  • 這將是最好的,以取代「4」與sizeof(int)每一次出現,無論你在呼喚readwrite 。您的機器上的整數可能是8個字節(64位整數?),儘管可能性不大。在將來,int更可能是8個字節,並且您的代碼在這方面非常脆弱。

也有一些「奇怪」的有關程序的,我觀察:

  • 爲什麼被前綴領先0(零)從printf輸出小數點?這將是一個八進制表示,但printf說明符不是"%o""%d"不應顯示前導零,除非您使用帶前導零的寬度說明符,即la "%08d"。所以我不知道該怎麼做。
+0

謝謝,初始化味精工作奇蹟! – w2lame 2010-08-10 19:43:00

+0

很高興聽到它。合十禮。 – 2010-08-10 19:43:51

+0

並再次感謝您提供的其他建議。他們真的幫助了我的計劃,也幫助了我。 :D – w2lame 2010-08-10 19:58:41

1

如果這是Linux,請嘗試使用strace來查看正在寫入管道的確切數據。

如果這是Solaris或Mac OS X,請嘗試dtrace或dtruss。

在BSD上我相信命令查看系統調用只是桁架。

這些是有用的命令。

+0

非常感謝您的建議。 – w2lame 2010-08-11 21:25:48

2

你不想調用叉兩次。 你也不想關閉管道的未使用的末端:)

+0

由於程序的性質,我應該撥4次撥號。但是,爲什麼我不應該關閉管道未使用的端點。我認爲這是一個很好的做法:) – w2lame 2010-08-10 19:58:10