如何使用fork运行异步创建3个进程

时间:2016-05-24 22:20:54

标签: c fork

我有问题, 我需要编写一个小型的c程序,打印出由三个进程给出的随机数,这些进程只会自己打印一个数字20次。

输出应该类似0122102021012021120...,并且从父进程完成。

我只获得如下输出:

00000000000000000000ready11111111111111111111readyready22222222222222222222readyreadyready

我不知道该怎么办 - 似乎我不理解fork()系统背后的基础逻辑;)

我的代码是:

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4
  5 void printfXtimes(int a, int b){
  6         int i;
  7         for(i=0;i<b;i++){
  8                 printf("%i",a);
  9                 sleep(1);
 10         }
 11 }
 12
 13 void main(){
 14         for(int kid = 0; kid < 3; ++kid) {
 15                 int pid = fork();
 16                 if(pid < 0){
 17                         exit(EXIT_FAILURE);
 18                 }else if (pid > 0){
 19                          /* Parent process */
 20                         printf("ready");
 21                 }else{
 22                         /* Child process */
 23                         printfXtimes(kid,20);
 24                         exit(EXIT_SUCCESS);
 25                 }
 26                 for (int kid = 0; kid < 3; ++kid) {
 27                         int status;
 28                         pid_t pid = wait(&status);
 29                 }
 30
 31         }
 32 }
这是错的吗? :/ 任务被认为是“容易的”......我不明白......

2 个答案:

答案 0 :(得分:3)

中等可行代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

static void printfXtimes(int a, int b)
{
    for (int i = 0; i < b; i++)
    {
        printf("%i\n", a);
        usleep(10000);
        //sleep(1);
    }
}

int main(void)
{
    for (int kid = 0; kid < 3; ++kid)
    {
        int pid = fork();
        if (pid < 0)
        {
            exit(EXIT_FAILURE);
        }
        else if (pid > 0)
        {
            /* Parent process */
            printf("PID %d ready\n", pid);
        }
        else
        {
            /* Child process */
            printfXtimes(kid, 10);
            exit(EXIT_SUCCESS);
        }
    }

    for (int kid = 0; kid < 3; ++kid)
    {
        int status;
        int corpse = wait(&status);
        printf("PID %d exited 0x%.4X\n", corpse, status);
    }
}

注意:

  • 使用fork()时,main()的正确返回类型为int,而非void。您可以在Windows上使用void main();在其他地方,它是错误的(几乎在其他任何地方 - 特定系统可以将其记录为正常,就像Windows一样)。请参阅What should main() return in C and C++?
  • 一个问题是,在你启动每个孩子后,你等待三个孩子死亡。该循环应该在启动循环之后。否则,您将强制执行顺序处理,而不是异步处理。
  • 另一个问题是你不要在消息的末尾使用换行符;这也会引起混淆(见printf() anomaly after fork())。

示例输出(无管道):

PID 34795 ready
PID 34796 ready
0
1
2
PID 34797 ready
0
1
2
0
1
2
0
1
2
0
1
2
0
1
2
1
2
0
1
0
2
1
0
2
1
2
0
PID 34795 exited 0x0000
PID 34797 exited 0x0000
PID 34796 exited 0x0000

示例输出(通过管道传输到sed):

0
0
0
0
0
0
0
0
0
0
PID 34789 ready
1
1
1
1
1
1
1
1
1
1
PID 34789 ready
PID 34790 ready
2
2
2
2
2
2
2
2
2
2
PID 34789 ready
PID 34790 ready
PID 34791 ready
PID 34789 exited 0x0000
PID 34791 exited 0x0000
PID 34790 exited 0x0000

如果您已阅读并理解“printf()”问题后的“fork()异常”,则应了解线路缓冲和完全缓冲,并且sed的输出应该是可解释的(特别是,为什么有PID nnnnn ready消息的额外副本。

答案 1 :(得分:1)

错过了{和}我认为并且缺少同花顺。没有经过编译测试:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void printfXtimes(int a, int b)
{
    int i;
    for(i=0;i<b;i++) {
        printf("%i",a);
        fflush(stdout);
        sleep(1);
    }
}

int main(int argc, char *argv[]){
    for(int kid = 0; kid < 3; ++kid) {
        int pid = fork();
        if(pid < 0){
            exit(EXIT_FAILURE);
        }else if (pid > 0){
            /* Parent process */
            printf("ready");
        }else{
            /* Child process */
            printfXtimes(kid,20);
            exit(EXIT_SUCCESS);
        }
    }
    for (int kid = 0; kid < 3; ++kid) {
        int status;
        pid_t pid = wait(&status);
    }
    return  0;
}