C语言进程(第一章进程基础,fork()函数,pid_t, pid, getpid())

  • 作者简介:一名后端开发人员,每天分享后端开发以及人工智能相关技术,行业前沿信息,面试宝典。
  • 座右铭:未来是不可确定的,慢慢来是最快的。
  • 个人主页极客李华-CSDN博客
  • 合作方式:私聊+
  • 这个专栏内容:BAT等大厂常见后端java开发面试题详细讲解,更新数目100道常见大厂java后端开发面试题。
  • 我的CSDN社区:https://bbs.csdn.net/forums/99eb3042821a4432868bb5bfc4d513a8
  • 微信公众号,抖音,b站等平台统一叫做:极客李华,加入微信公众号领取各种编程资料,加入抖音,b站学习面试技巧,职业规划

C语言进程(第一章进程基础,fork()函数,pid_t, pid, getpid())

简介

当我们用c编程构建一个应用时,常常会遇到这样的场景:需要在程序中同时完成几项任务,如处理数据、打印输出、和读取用户输入等。 这种需要同时进行多项任务效率更高的需求,就是“并发”。

一般由操作系统负责协调和分配计算机资源, 管理“进程”和“线程”。在c语言中,我们可以使用进程和线程来实现并发执行的目的。

  • 进程(process) 是操作系统管理资源,供程序运行时需要访问和控制的运行空间和内存地址。每个进程拥有自己的内存空间、系统资源、打开文件以及与其他进程的互动等等。

我们常把整个程序作为一个进程来处理,但是一个程序同时可能包含多个运行实例,即多个进程。 比如的浏览器中同时执行浏览网页、下载文件、播放视频等很多任务,那这些任务就会在不同的进程中执行。

入门

相关在线编辑网站:https://www.ideone.com/whPQYr

当学习进程和线程这些概念之后,下面是一些适合入门的C语言案例如下:

  1. 创建一个简单的进程
#include <stdio.h>
#include <stdlib.h> 
#include <unistd.h> 

int main() {
    pid_t pid;
    pid = fork();

    if (pid == -1) {
        printf("error: 创建进程失败 \n");
        exit(1);
    } else if (pid == 0) {
        printf("我是子进程,我的pid是 %d \n", getpid());
    } else {
        printf("我是父进程,我的pid是 %d \n", getpid());
    }

    return 0;
}

该程序使用fork()函数创建新进程。如果pid值小于0,则fork()系统调用失败并且创建一个新进程将无法完成;如果pid等于0,则说明当前运行的进程为子进程。所以我们执行该程序可以得到父进程的进程 id 和子进程的进程 id。

运行结果
在这里插入图片描述
运行结果解释:
这个程序运行的输出结果是:

我是父进程,我的pid是 3173 
我是子进程,我的pid是 3213 

在程序运行时,当 fork() 函数被调用时,进程会生成一个新的地址空间,然后把父进程的数据拷贝到新的地址空间中。新的进程就是所谓的子进程,它与父进程几乎完全相同,只有进程 ID 不同。

  • 在父进程中,fork()函数返回子进程的进程 ID 号,也就是变量 pid 值大于 0,如果pid等于-1,则说明进程创建失败。
  • 在子进程中,fork()函数返回0,因此在代码块 else if (pid == 0) 中执行,
    输出 “我是子进程,我的pid是 xxx” 的格式化字符串,使用 getpid() 来获取子进程的PID号码。
  • 在父进程中,在 else 语句块中执行,打印 “我是父进程,我的pid是 xxx”。使用 getpid() 来获取父进程自己的 PID 号。

两个打印信息出现的顺序是不确定的,这取决于操作系统选择在哪个进程上运行,这在每台计算机和每种操作系统都可能会有所不同。

fork()

fork()函数是Unix操作系统中创建新进程的一个函数。在C语言中,可以使用这个函数来创建新进程。

具体地说,当程序执行到 fork()函数时,它会创建一个子进程并使其运行同样的代码,相当于将原来的进程“复制”一份,形成了两个几乎完全相同的进程。其中,原有进程称为父进程,新创建出来的进程称为子进程。而在父进程和子进程中,通过fork()函数的返回值来区分不同进程,因为在子进程中,fork()函数将返回0,在父进程中,该值将是它所创建的子进程的进程ID。

fork() 函数可以用来实现普通进程的派生,也可以在后续中使用 execve() 系列函数去加载不同命令。

下面是基本的fork()函数使用案例:

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

int main() {
    pid_t pid;
    pid = fork();

    if (pid == -1) {
        printf("error: 创建进程失败 \n");
        exit(1);
    } else if (pid == 0) {
        printf("我是子进程,我的pid是 %d \n", getpid());
    } else {
        printf("我是父进程,我的pid是 %d \n", getpid());
    }

    return 0;
}

在这个例子里,调用fork()函数创建了一个子进程。如果fork()函数调用失败,那么就会返回-1;在子进程时,其返回值为0,而在父进程时其返回值是子进程 ID。

需要注意的是,fork()函数非常耗费资源,因为该函数需要拷贝整个进程。因此在代码中应当尽量避免使用超过必要的fork()函数调用,在多次使用时也需要减少系统资源消耗和时间延迟等方面进行优化。

运行结果:
在这里插入图片描述

pid

pid 是 “process ID” 的缩写,即进程ID。

在操作系统中,每个正在运行的进程都会被分配一个唯一的整数进程 ID (PID),用于标识该进程。进程 ID 在系统内部用作识别进程、管理进程状态等方面起着非常重要的作用,这意味着唯一的PID意味着对应唯一的进程标识符。在 Linux 和 Unix 系统中,可以使用 ps 命令和其他系统工具来查看当前运行的进程及其 PID。

你可以通过编写 shell 脚本 或 C 语言程序来获得当前进程的 pid,使用 getpid()函数,如下所示:

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

int main() {
    printf("当前进程的pid是:%d\n", getpid());
    return 0;
}

在该程序中,使用getpid()函数获取当前进程的 PID,并把其打印出来。因为每个进程的PID都是独特的,运行该程序时,您将会得到一个不同于其他正在运行进程的独特 PID 值输出结果。

总之,在操作系统中了解和使用进程 ID 很重要,这有助于开发人员和系统管理员进行多种监控和管理活动,以及进行更好的调试和错误处理。

运行结果
在这里插入图片描述

pid_t

在 C 语言中,pid_t 是一个整数类型,用于表示进程的 ID 。具体来说,在绝大多数 Unix 或 Linux 系统中,pid_t 的定义如下:

typedef int pid_t;

因此,pid_t 实际上是 int 类型,而且在一般情况下其大小与 int 相等。

使用 pid_t 这种类型是为了能够让代码更加可移植。因为不同平台之间对于进程ID的实现可能会有所不同,比如 Windows 平台就使用 HANDLE 类型而非 pid_t;在32位系统和64位系统上PID最大值也可能不同,而使用这种类型可以保证程序在不同的平台上都能正常编译和运行。因此,在编写依赖于进程ID的程序时,最好使用 pid_t 而非硬编码整数类型。

在 C 标准库 <unistd.h>中,fork() 函数说明返回一个 pid_t 类型的值,从而方便地获得新创建进程的 PID 号,示例代码如下:

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

int main() {
    pid_t pid;
    pid = fork();

    if (pid == -1) {
        printf("error: 创建进程失败 \n");
        exit(1);
    } else if (pid == 0) {
        printf("我是子进程,我的pid是 %d \n", getpid());
    } else {
        printf("我是父进程,我的pid是 %d \n", getpid());
    }

    return 0;
}

在该程序中,定义 pid_t pid 来保存进程 ID 值,即 fork 函数返回值。这有助于让您的代码更符合 C 标准,并以可移植方式使用操作系统提供的功能。

如果大家觉得有用的话,可以关注我下面的微信公众号,极客李华,我会在里面更新更多行业资讯,企业面试内容,编程资源,如何写出可以让大厂面试官眼前一亮的简历等内容,让大家更好学习编程,我的抖音,B站也叫极客李华。大家喜欢也可以关注一下

  • 10
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客李华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值