2014-10-19 48 views
0

我道歉,但我的英語,我希望你能明白。 所以我有我的程序中的printf這個問題,等待父親的結束和一些printf之前。所以我總是得到父親打印他所有的信息,然後兒子printf他所有的信息,而它應該交叉..錯誤printf在叉

從我看到的,我讀了,我必須有fflush,但它不能解決我的問題。 Thx爲您提供幫助。 這是我的代碼。

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <sys/sem.h> 
#include <sys/ipc.h> 
#include <unistd.h> 
#include <sys/shm.h> 

int cpt = 0; 

void fils(int *cpt){ 
    int i; 
    for(i = 0; i < 3; i++){ 
    (*cpt)++; 
    printf("son : %d\n", *cpt); 
    } 
} 

void pere(int *cpt){ 
    int i; 
    for(i = 0; i < 3; i++){ 
    (*cpt)--; 
    printf("father : %d\n", *cpt); 
    fflush(stdout); 
    } 
} 

int main (int argc, char*argv[]){ 
    key_t key; 
    int memShared; 
    int *cpt = NULL; 

    key = ftok(argv[0],'p'); 
    memShared = shmget(key, sizeof(int), IPC_CREAT|IPC_EXCL|0666); 
    cpt = shmat (memShared, cpt, 0); 
    *cpt = 0; 

    fflush(stdout); 
    switch (fork()){ 
    case -1: perror("erreur de création du fils"); 
     exit(99); 
    case 0: fils(cpt); 
     exit(1); 
    default: pere(cpt); 
     wait(NULL); 
    } 
    shmctl(memShared, IPC_RMID, NULL); 

    return 0; 
} 

和我總是有這樣的在終端

父親:-1 父親:-1 父親:-2 子:0 子:-1 子:0

我雖然應該交叉,例如父親:-1兒子:0父親:-1 ... 感謝您的幫助。

+6

你說「它應該交叉」,但你沒有實現這樣做的機制。這兩個過程都只是爲了寫出所有的輸出,你的程序中沒有任何東西可以讓你等待另一個。如果你想讓他們交替輸出,你必須編寫代碼讓他們做到這一點。你也不會同步對共享內存的訪問,這就是爲什麼你會得到奇數輸出,比如父親連續寫兩個'-1'。 – 2014-10-19 19:17:28

+0

您總是需要將'fork'的結果保存在一個變量中,因爲父親需要'waitpid'。另請參閱[shm_overview(7)](http://man7.org/linux/man-pages/man7/shm_overview.7.html)和[sem_overview(7)](http://man7.org/linux/man -pages/man7/sem_overview.7.html) – 2014-10-19 19:17:38

+2

@BasileStarynkevitch:不需要。他正在等待任何一個子進程完成。這足夠有選擇性。 (我們不是在一般情況下,真正必須使用'waitpid'。) – Deduplicator 2014-10-19 19:21:44

回答

0

這是一場經典比賽。爲了實現「兒子第一次」的順序只是重新排序線switch

switch (fork()){ 
case -1: perror("erreur de création du fils"); 
    exit(99); 
case 0: fils(cpt); 
    exit(1); 
default: wait(NULL); //First - wait 
    pere(cpt);  //Then - print 
} 

你有沒有保證,你打算這樣簡單的解決方案是否能正常工作。你想要的是確保只有一個循環迭代被一個進程執行直到它被關閉。

如果你想確保他們以這種ABABAB的方式去,那麼你需要另一種同步機制。請記住,簡單的信號量是不夠的。你可能想要一個管道或一個FIFO隊列來允許這個進程進行通信。尋找名爲pipemkfifo的函數。比你可以這樣去:

for(number_of_iterations) 
{ 
    wait for a message from the other process; 
    do work on shm; 
    send message to another process, allowing it to continue; 
} 

這會激發令牌的概念。

至於評論中的建議:保持分支結果爲變量a,則等待waitpid時更安全,因爲wait等待第一個結束進程,而不是特定進程。

-1
[email protected]:~$ 
[email protected]:~$ ./wrong_printf 
father : -1 
son : 0 
son : 1 
son : 2 
father : 1 
father : 0 
[email protected]yf1:~$** 

我的電腦上的程序工作。我的意思是父親的printf和兒子的printf確實被穿過了。

+0

沒關係。這個程序**可能**工作,但不**保證**工作。這通常是種族問題。 – 2014-10-20 05:24:03