• 对fork()函数的理解 分类: C/C++ 2015-07-29 14:20 4人阅读 评论(0) 收藏


    头文件: #include <unistd.h>

    1. pid_t fork (void);  

    1. 创建一个子进程,失败返回-1。

    2. 调用一次,返回两次。分别在父子进程中返回子进程的PID和0。利用返回值的不同,可以分别为父子进程编写不同的处理分支。
    1. #include <stdio.h>  
    2. #include <unistd.h>  
    3.   
    4. int main (void) {  
    5.     printf ("%u进程:我要调用fork()了... ", getpid ());  
    6.   
    7.     pid_t pid = fork ();  
    8.     if (pid == -1) {  
    9.         perror ("fork");  
    10.         return -1;  
    11.     }  
    12.   
    13.     if (pid == 0) {  
    14.         printf ("%u进程:我是%u进程的子进程。 ", getpid (),  
    15.             getppid ());  
    16.         return 0;  
    17.     }  
    18.   
    19.     printf ("%u进程:我是%u进程的父进程。 ", getpid (), pid);  
    20.     sleep (1);  
    21.   
    22.     return 0;  
    23. }  


    3. 子进程是父进程的副本,子进程获得父进程数据段和堆栈段(包括I/O流缓冲区)的拷贝,但子进程共享父进程的代码段。
    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <unistd.h>  
    4.   
    5. int global = 100;  
    6.   
    7. int main (void) {  
    8.     int local = 200;  
    9.     char* heap = (char*)malloc (256 * sizeof (char));  
    10.     sprintf (heap, "ABC");  
    11.     printf ("父进程:%d %d %s ", global, local, heap);  
    12.     pid_t pid = fork ();  
    13.     if (pid == -1) {  
    14.         perror ("fork");  
    15.         return -1;  
    16.     }  
    17.   
    18.     if (pid == 0) {  
    19.         global++;  
    20.         local++;  
    21.         sprintf (heap, "XYZ");  
    22.         printf ("子进程:%d %d %s ", global, local, heap);  
    23.         free (heap);  
    24.   
    25.         return 0;  
    26.     }  
    27.   
    28.     sleep (1);  
    29.     printf ("父进程:%d %d %s ", global, local, heap);  
    30.     free (heap);  
    31.   
    32.     return 0;  
    33. }  

    1. #include <stdio.h>  
    2. #include <unistd.h>  
    3.   
    4. int main (void) {  
    5.     printf ("ABC");  
    6.   
    7.     pid_t pid = fork ();  
    8.     if (pid == -1) {  
    9.         perror ("fork");  
    10.         return -1;  
    11.     }  
    12.   
    13.     if (pid == 0) {  
    14.         printf ("XYZ ");  
    15.         return 0;  
    16.     }  
    17.   
    18.     sleep (1);  
    19.     printf (" ");  
    20.   
    21.     return 0;  
    22. }  


    4. 函数调用后父子进程各自继续运行,其先后顺序不确定。某些实现可以保证子进程先被调度。
    1. #include <stdio.h>  
    2. #include <unistd.h>  
    3.   
    4. int main (void) {  
    5.     printf ("父进程:");  
    6.     int a, b, c;  
    7.     scanf ("%d%d%d", &a, &b, &c);  
    8.   
    9.     pid_t pid = fork ();  
    10.     if (pid == -1) {  
    11.         perror ("fork");  
    12.         return -1;  
    13.     }  
    14.   
    15.     if (pid == 0) {  
    16.         scanf ("%d%d%d", &a, &b, &c);  
    17.         printf ("子进程:%d %d %d ", a, b, c);  
    18.   
    19.         return 0;  
    20.     }  
    21.   
    22.     sleep (1);  
    23.     printf ("父进程:%d %d %d ", a, b, c);  
    24.   
    25.     return 0;  
    26. }  


    5. 函数调用后,  父进程的文件描述符表(进程级)也会被复制到子进程中,二者共享同一个文件表(内核级)。
    1. #include <stdio.h>  
    2. #include <string.h>  
    3. #include <fcntl.h>  
    4. #include <unistd.h>  
    5.   
    6. int main (void) {  
    7.     int fd = open ("ftab.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);  
    8.     if (fd == -1) {  
    9.         perror ("open");  
    10.         return -1;  
    11.     }  
    12.   
    13.     const char* text = "Hello, World !";  
    14.     if (write (fd, text, strlen (text) * sizeof (text[0])) == -1) {  
    15.         perror ("write");  
    16.         return -1;  
    17.     }  
    18.   
    19.     pid_t pid = fork ();  
    20.     if (pid == -1) {  
    21.         perror ("fork");  
    22.         return -1;  
    23.     }  
    24.   
    25.     if (pid == 0) {  
    26.         if (lseek (fd, -7, SEEK_CUR) == -1) {  
    27.             perror ("lseek");  
    28.             return -1;  
    29.         }  
    30.   
    31.         close (fd);  
    32.         return 0;  
    33.     }  
    34.   
    35.     sleep (1);  
    36.     text = "Linux";  
    37.     if (write (fd, text, strlen (text) * sizeof (text[0])) == -1) {  
    38.         perror ("write");  
    39.         return -1;  
    40.     }  
    41.     close (fd);  
    42.     return 0;  
    43. }  
    结果:Hello ,Linux !

    6. 总进程数或实际用户ID所拥有的进程数, 超过系统限制,该函数将失败。

    7. 一个进程如果希望创建自己的副本并执行同一份代码,或希望与另一个程序并发地运行,都可以使用该函数。

    注意:fork之前的代码只有父进程执行,fork之后的代码父子进程都有机会执行, 受代码逻辑的控制而进入不同分支。
  • 相关阅读:
    dubbo踩坑
    windows下面使用protobuf
    解决端口占用的问题
    建设检验
    统计学资料整理
    java cpu 负载高分析
    演讲/汇报
    管理和领导
    css渐变动画
    vue组件之间互相传值:父传子,子传父
  • 原文地址:https://www.cnblogs.com/zclzqbx/p/4687024.html
Copyright © 2020-2023  润新知