2014-12-13 98 views
2

所以我開始瞭解流程是如何工作的並且編寫了一些簡單的代碼。爲什麼進程子執行一些意外的行?

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 
int SemId; 
void SemGet(int n) 
{ 
    SemId = semget(IPC_PRIVATE, n, 0600); 
    if (SemId == -1) { 
     exit(1); 
    } 
} 
int SemSetVal(int SemNum, int SemVal) 
{ 
    return semctl(SemId, SemNum, SETVAL, SemVal); 
} 
int SemOp(int SemNum, int SemOp) 
{ 
    struct sembuf SemBuf; 
    SemBuf.sem_num = SemNum; 
    SemBuf.sem_op = SemOp; 
    SemBuf.sem_flg = 0; 
    return semop(SemId, & SemBuf, 1); 
} 
void SemRemove(void) 
{ 
    (void) semctl(SemId, 0, IPC_RMID, 0); 
} 

void child(int vchild) { 
    printf("\nChild %d", vchild); 
    return; 
} 

int main(int argc, char** argv) { 
    printf("\nHeeeyoooo!"); 

    if (fork() == 0) { 
     child(1); 
     exit(0); 
    } 
    (void) wait(NULL); 
    printf("\nParent."); 

    return 0; 
} 

和我所得到的輸出是

Heeeyoooo! 
Child 1Heeeyoooo! 
Parent. 
Process returned 0 (0x0) execution time : 0.001 s 
Press ENTER to continue. 

爲什麼我會收到 「heyooo」 兩次? 我好像孩子正在恢復到主,而不是由出口遭到停...

+0

使用'printf(「Child%d \ n」,child);' – 2014-12-13 14:02:09

+0

那不是問題 – ditoslav 2014-12-13 14:06:19

+0

好吧,'\ C'應該會產生錯誤。 'exit()'應該在'stdlib.h'中。 'fork()'在'unistd.h'中。你在做什麼呢 ? :-) – 2014-12-13 14:23:37

回答

3

child is getting back into the main instead of getting terminated by the exit ..不,情況並非如此。

你的代碼有很多問題。

  1. \Child會給你錯誤的「未知的轉義序列」,改爲\nChild
  2. 包括stdlib.h對於exit()
  3. 包括unistd.h用於fork()
  4. 添加\nprintf("Heeeyoooo!");到刷新輸出緩衝區。

1,2和3後,在代碼中問題是,沒有newline escape sequence存在於您的printf()這就是爲什麼你的輸出緩衝區不沖洗。因此,要在下次打印之前清除標準輸出緩衝區,請添加一個換行符轉義序列[\n],這將刷新緩衝區。

提的價值,從fork()man page

子進程應有自己父母的開放 目錄流的副本。在子過程中的每個打開的目錄流可以與父

這意味着,沒有緩衝的沖洗的相應目錄 流 共享目錄流定位,Heeeyoooo!仍然存在於孩子的輸出流,因此它再次打印。

+0

這些都是一些快速編輯錯誤,代碼在gcc代碼塊中編譯 – ditoslav 2014-12-13 14:41:38

+0

/stnbuff總是一個可行的flush? – ditoslav 2014-12-13 14:42:47

+0

@DominikDitoIvosevic正如我所說的,第4點是_prime_問題。其他問題。 :-) – 2014-12-13 14:43:18

2

如果你寫

printf("Heeeyoooo!"); 
fflush(stdout); 

,然後叉,錯誤消失。原因是fork()克隆了標準輸出的輸出緩衝區,而"Heeeyoooo!"仍在其中,所以隨後打印兩次。