进程学习:初见进程

来源:互联网 发布:网络包装公司是干嘛的 编辑:程序博客网 时间:2024/05/22 05:01

进程
pid_t fork(void);
功能:创建一个新的进程
参数:无
返回值:
成功:如果是父进程返回子进程的pid号;如果是子进程返回0;
失败:返回-1

特点一:调用一次,返回两次

#include <stdio.h>#include <unistd.h>#include <stdlib.h>int main(int argc, const char *argv[]){    pid_t pid;    if( (pid = fork()) < 0)    {        perror("fork error");        exit(1);    }    else if(pid == 0)    {        printf("im child process\n");    }    else if(pid > 0)    {        waitpid(pid, NULL, 0);        printf("im farther process\n");    }    printf("this is a fork fuction, pid = %d\n", pid);    return 0;}

编译运行(如下图):
调用一次,返回两次
第一个“this is a fork fuction,pid = 0”是子进程打印的;
第二个“this is a fork fuction,pid = 3089”是父进程打印的;

why?
因为以阻塞的方式调用了waitpid函数,所以父进程在waitpid这一直处于阻塞等待,直到子进程退出才继续往下执行(看看pid的值);


特点二:子进程执行的位置

子进程是父进程的副本,它将获得父进程数据空间、堆、栈、缓冲区等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。
这里写图片描述

#include <stdio.h>#include <unistd.h>#include <stdlib.h>int main(int argc, const char *argv[]){    pid_t pid;    printf("this is a fork fuction\n");    if( (pid = fork()) < 0)    {        perror("fork error");        exit(1);    }    else if(pid == 0)    {        printf("im child process\n");    }    else if(pid > 0)    {        waitpid(pid, NULL, 0);        printf("im farther process\n");    }    printf("hello world, pid = %d\n", pid);    return 0;}

看看进程的执行特点:程序从fork处开始分裂成两个进程,两个进程拥有相同的代码段、缓冲区等,但是子进程是从fork后边开始执行的,所以上边的程序只会执行一次“this is a fork fuction”,是父进程执行的,子进程是不执行这里的代码的,但是这里也被它复制过去了;
程序编译执行(如下图):
这里写图片描述


特点三:复制缓冲区

#include <stdio.h>#include <unistd.h>#include <stdlib.h>int main(int argc, const char *argv[]){    pid_t pid;    //注意,将这里的\n去掉了,此时,行缓存不会刷新    printf("this is a fork fuction");    if( (pid = fork()) < 0)    {        perror("fork error");        exit(1);    }    else if(pid == 0)    {        printf("***im child process\n");    }    else if(pid > 0)    {        waitpid(pid, NULL, 0);        printf("***im farther process\n");    }    return 0;}

编译执行(如下图):
这里写图片描述
“this is a fork function”将\n去掉后,没有刷新行缓存,直到子进程中遇到了\n,刷新了行缓存,直接连原来缓冲区中的这一句与子进程中的语句一起打印了出来;
由于父子进程拥有相同的代码,只是执行的位置不一样,所以父进程遇见\n同样连同原来的语句一同打印出来;

知识点穿插:
行缓存刷新的条件?
这里写图片描述

这里强调一下,只有正常退出才会刷新缓存:

#include <stdio.h>int main(int argc, const char *argv[]){    printf("hello world");    while(1)        ;    return 0;}

编译执行:
while
行缓存没有被写满(行缓存1k,这几个字符不够),没有遇见\n,所以,程序执行时会一直进行死循环;
现在用kill -9 来杀死它,这属于非正常退出了,看看缓存区刷不刷新?
kill -9

这里写图片描述
看到了吧,hello world没有打印出来,说明行缓存没有刷新。

原创粉丝点击