fork函数如何创建进程,exit/_exit函数如何使进程终止的详细分析与代码实现

这篇具有很好参考价值的文章主要介绍了fork函数如何创建进程,exit/_exit函数如何使进程终止的详细分析与代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

fork函数如何创建进程,exit/_exit函数如何使进程终止的详细分析与代码实现

🎊【进程通信与并发】专题正在持续更新中,进程,线程,IPC,线程池等的创建原理与运用✨,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏

🪔本系列专栏 -  ​​​​​​并发与进程通信

🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️

📌个人主页 - 勾栏听曲_0的博客📝

🔑希望本文能对你有所帮助,如有不足请指正,共同进步吧🏆

🎇我见青山多妩媚,料青山见我应如是。📈

目录

fork创建进程

介绍

接口

代码实例

思考

终止进程

exit/_exit函数

接口

代码实例


fork创建进程

介绍

        fork用来创建一个新进程(child proccess),你要创建一个新进程,首先得知道一个进程中都包含上面东西。

        系统数据

        用户数据

        指令

         fork一个新进程时,这个新进程的 数据 和 指令 来源于哪里呢?

                来源于它爸爸(父进程,调用fork的那个进程)

        fork这个函数在创建子进程时,都复制了父进程的哪些内容呢:  

                copy了父进程的数据和指令!!!
                父进程的变量,数据对象,
                标准IO缓冲区
                文件描述符
                ...
                copy完了后,父子进程就独立啦。

            通过fork的不同的返回值,来区分到底是父进程返回,还是子进程返回。

接口

头文件 

            #include <sys/types.h>
            #include <unistd.h>

        函数功能

            创建一个子进程

        函数原型

             pid_t fork(void);

        函数参数

            无

        函数返回值

            如果失败返回-1,同时errno被设置。

            如果成功:  

                父进程返回 子进程的pid( > 0) 

                子进程返回  0

代码实例

        以下是获取自己的进程ID与获取父进程的IP的函数

                头文件 

                #include <sys/types.h>
                #include <unistd.h>

            函数原型 

                pid_t getpid(void);  //用于获取自己的进程pid 
                pid_t getppid(void); //用于获取父进程的pid 

        以下代码实现创建一个子进程,并且父子进程分别输出自己的id。

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>

int main()
{
	pid_t pid = fork();
	if(-1 == pid)
	{
		perror("fork failed!");
		return -1;
	}
	else if(0 == pid)	//子进程
	{
		printf("这是子进程,我的ID为%d\n",getpid());
		printf("这是子进程,我的父进程ID为%d\n",getppid());
	}
	else if(pid > 0)
	{
		printf("这是父进程,我的ID为%d\n",getpid());
		printf("这是父进程,我的子进程ID为%d\n",pid);
		printf("这是父进程,我的父进程ID为%d\n",getppid());;
	}
	return 0;
}

思考

        (1) fork一旦成功,就会有父进程和子进程,那么fork之后,到底是父进程先执行,还是子进程先执行呢?

        (2)fork子进程会拷贝父进程的指令和数据,它到底拷贝了父进程哪些数据呢? 

                    a:父进程全部的用户数据
                    b:父进程打开的文件描述符及状态
                    c:标准IO的缓冲区  
                    d:信号的处理方式

         (3)fork之后的子进程与父进程有什么区别?

                进程ID不同。子进程可以通过getpid()函数获取自己的进程ID,可以通过getppid()函数获取父进程的进程ID。
                子进程中的tms_utime tms_stime tms_cutime 和 tms_ustime的值设为0。
                子进程不继承父进程设置的文件锁,但继承了父进程中的所有互斥锁、读写锁和条件变量(包括它们的状态)。
                子进程拥有自己独立的地址空间,但是在fork之后exec之前两个进程用的是同一份物理页面。
                子进程的执行顺序和父进程是不确定的,取决于系统调度。

终止进程

        进程的终止一般有两种情况:第一是自己退出,常见的方法为main函数返回值,程序退出。第二种情况就是调用一些进程退出函数执行终止进程,例如exit/_exit函数与wait/waitpid函数。接下来外面就重点来讲解这两类程序退出函数。

exit/_exit函数

        exit函数和_exit函数都是用来终止进程的,但它们有以下区别:

                exit函数在终止进程之前,会先执行一些清理操作,比如调用atexit注册的函数,刷新所有文件缓冲区,关闭所有打开的文件描述符,销毁线程本地对象等。_exit函数则直接进入内核,不做任何清理操作。

                exit函数的参数是一个无符号整型,表示进程的退出状态,只有第八位有效(0-255),超出255将表示未定义退出状态值。_exit函数的参数是一个整型,表示进程的退出状态,但不一定是0-255。

                exit函数是标准C库函数,定义在<stdlib.h>头文件中。_exit函数是POSIX系统调用,定义在<unistd.h>头文件中。

接口

        头文件 

                     #include <stdlib.h>

                函数功能 

                    让进程退出,正常退出,做一些清理工作(如:把缓冲区的内容,同步到文件中去)

                函数原型

                    void exit(int status);

                函数参数

                    int status    //表示退出码,表示退出状态,退出码的具体含义,由程序员来解释。    
                函数返回值 

                    无


                头文件  

                     #include <unistd.h>

                函数功能

                    _exit 坐火箭走的,让中止进程,来不及做清理工作

                函数原型 

                     void _exit(int status);

                函数参数  

                    int status    //表示退出码,表示退出状态,退出码的具体含义,由程序员来解释。

                函数返回值

                    无

代码实例

        你可以使用命令行参数来指定文件名和打开模式,然后根据模式来调用exit()函数或_exit()函数。例如,你可以输入./a.out test.txt w来打开test.txt文件并写入内容,或者输入./a.out test.txt r _exit来打开test.txt文件并读取内容,然后调用_exit()函数。文章来源地址https://www.toymoban.com/news/detail-454501.html

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

int main(int argc, char *argv[])
{
    if (argc < 3) // 检查命令行参数是否足够
    {
        printf("Usage: %s filename mode [exit_mode]\n", argv[0]); // 输出用法提示
        return 1;
    }
    char *filename = argv[1]; // 获取文件名
    char *mode = argv[2]; // 获取打开模式
    char *exit_mode = argv[3]; // 获取退出模式
    FILE *fp = fopen(filename, mode); // 打开文件
    if (fp == NULL) // 检查文件是否打开成功
    {
        printf("Cannot open file %s\n", filename); // 输出错误信息
        return 2;
    }
    if (strcmp(mode, "w") == 0) // 如果是写入模式
    {
        printf("Writing to file %s\n", filename); // 输出提示信息
        fprintf(fp, "Hello, file!\n"); // 写入内容到文件
    }
    else if (strcmp(mode, "r") == 0) // 如果是读取模式
    {
        printf("Reading from file %s\n", filename); // 输出提示信息
        char buffer[100]; // 定义缓冲区
        while (fgets(buffer, 100, fp) != NULL) // 循环读取文件内容
        {
            printf("%s", buffer); // 输出文件内容到标准输出
        }
    }
    else // 如果是其他模式
    {
        printf("Invalid mode %s\n", mode); // 输出错误信息
        fclose(fp); // 关闭文件
        return 3;
    }
    fclose(fp); // 关闭文件
    if (exit_mode != NULL && strcmp(exit_mode, "_exit") == 0) // 如果指定了_exit()函数
    {
        _exit(0); // 调用_exit()函数
    }
    else // 否则
    {
        exit(0); // 调用exit()函数
    }
    
}

到了这里,关于fork函数如何创建进程,exit/_exit函数如何使进程终止的详细分析与代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux——进程创建与进程终止

    📘北尘_ :个人主页 🌎个人专栏 :《Linux操作系统》《经典算法试题 》《C++》 《数据结构与算法》 ☀️走在路上,不忘来时的初心 在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。 #include unistd.h pid_t fork(void); 返

    2024年02月04日
    浏览(29)
  • 【Linux进程控制】进程创建 | 进程终止 | 进程等待 | 进程替换

    【写在前面】 本文主要学习理解 fork 的返回值、写时拷贝的工作细节、为什么要存在写时拷贝;进程退出码、进程退出的场景及常见的退出方法、对比 man 2 _exit 和 man 3 exit;进程终止、操作系统怎么进行释放资源、池的概念;进程等待的价值、进程等待的方法 wait 和 waitpid

    2023年04月08日
    浏览(29)
  • 【Linux】进程控制(创建、终止、等待)

    环境:centos7.6,腾讯云服务器 Linux文章都放在了专栏:【 Linux 】欢迎支持订阅 相关文章推荐: 【Linux】冯.诺依曼体系结构与操作系统 【Linux】进程理解与学习Ⅰ-进程概念 【Linux】进程理解与学习Ⅱ-进程状态 【Linux】进程理解与学习Ⅲ-环境变量 【Linux】进程理解与学习Ⅳ

    2023年04月16日
    浏览(47)
  • Linux进程控制【创建、终止、等待】

    ✨个人主页: Yohifo 🎉所属专栏: Linux学习之旅 🎊每篇一句: 图片来源 🎃操作环境: CentOS 7.6 阿里云远程服务器 Good judgment comes from experience, and a lot of that comes from bad judgment. 好的判断力来自经验,其中很多来自糟糕的判断力。 进程 创建后,需要对其进行合理管理,光靠

    2024年02月02日
    浏览(30)
  • 【Linux】进程查看|fork函数|进程状态

    🦄 个人主页—— 🎐 开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁 🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁🍁🪁🍁🪁 🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁 感谢点赞和关注 ,每天进步一点点!加油! 目录 一、基本概念 1.1 概念提出 1.2 特征 二、描述进程-PCB 2.1 什么是进程

    2024年02月04日
    浏览(30)
  • Linux:创建进程 -- fork,到底是什么?

     相信大家在初学进程时,对fork函数创建进程一定会有很多的困惑,比如: 1.fork做了什么事情??  2.为什么fork函数会有两个返回值? 3.为什么fork的两个返回值,会给父进程谅回子进程pid,给子进程返回0? 4.fork之后:父子进程谁先运行?? 5.如何理解同一个变量,会有不同的值?? 本

    2024年02月05日
    浏览(29)
  • fork()函数创建子进程

    fork()用于创建子进程, 一次调用 会有 两个返回 (return),一次返回给父进程子进程的PID(Process ID),一次返回给子进程,其返回值为0. 返回值=0,子进程在运行 返回值0,父进程在运行 返回值0,fork()调用出错 进程获取 自己的PID:getpid() 进程获取 父进程PID:getppid() 由于一个进

    2023年04月08日
    浏览(31)
  • [Linux]进程控制详解!!(创建、终止、等待、替换)

            hello,大家好,这里是bang___bang_,在上两篇中我们讲解了进程的概念、状态和进程地址空间,本篇讲解进程的控制!!包含内容有进程创建、进程等待、进程替换、进程终止!! 附上前2篇文章链接: Linux——操作系统进程详解!!(建议收藏细品!!)_bang___ba

    2024年02月15日
    浏览(31)
  • 头歌(Linux之进程管理一):第2关:进程创建操作-fork

    任务描述 在上一关我们学习如何获取进程的 pid 信息,本关我们将介绍如何编程创建一个新的进程。 本关任务:学会使用 C 语言在 Linux 系统中使用 fork 系统调用创建一个新的进程。 相关知识 在 Linux 系统中创建进程有很多函数可以使用,其中包括了系统调用也包括库函数。

    2024年02月06日
    浏览(29)
  • 【Linux初阶】进程的相关概念 | 进程管理 & 查看进程 & 获取进程标识符 & fork进程创建

     🌟hello,各位读者大大们你们好呀🌟 🍭🍭系列专栏:【Linux初阶】 ✒️✒️本篇内容:进程的概念,进程管理初识(描述、管理进程),查看进程的基础方法,获取进程标识符(pid、ppid),fork进程创建(分流应用) 🚢🚢作者简介:计算机海洋的新进船长一枚,请多多

    2023年04月27日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包