2014-10-19 43 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