2014-12-13 66 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!"仍在其中,所以随后打印两次。