为什么进程子进程会执行一些意外的行?

时间:2014-12-13 13:56:03

标签: c process parent-child

所以我开始知道流程是如何工作的,并编写了一些简单的代码。

#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”? 我好像孩子正在回到主楼,而不是被出口终止......

2 个答案:

答案 0 :(得分:3)

child is getting back into the main instead of getting terminated by the exit ..不,事实并非如此。

您的代码存在许多问题。

  1. \Child会在&#34;未知转义序列&#34;方面给您错误,更改为\nChild
  2. 包括stdlib.h的{​​{1}}。
  3. 包含exit() unistd.h
  4. fork()添加到\n以刷新输出缓冲区。
  5. 在1,2和3之后,代码中的 main 问题是,printf("Heeeyoooo!");中没有newline escape sequence,这就是为什么输出缓冲区没有刷新的原因。因此,要在下次打印之前清除标准输出缓冲区,请添加一个换行缓冲区[printf()]的换行符。

    值得一提的是,来自\n

    man page
      

    子进程应拥有自己的父进程副本   目录流。子进程中的每个打开的目录流都可以   与相应目录共享目录流定位   父母的流

    这意味着,在没有刷新缓冲区的情况下,fork()仍然存在于子输出流中,因此会再次打印。

答案 1 :(得分:2)

如果你写

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

然后fork,错误就消失了。原因是fork()克隆了stdout的输出缓冲区,而"Heeeyoooo!"仍在其中,因此随后打印两次。