Linux应用编程

2023-11-11

进程控制

fork函数

函数说明:创建一个子进程。

函数原型:pid_t fork(void);

返回值:失败返回-1;成功返回:① 父进程返回子进程的ID(非负)     ②子进程返回 0

pid_t类型表示进程ID,但为了表示-1,它是有符号整型。(0不是有效进程ID,init最小,为1)

注意返回值,不是fork函数能返回两个值,而是fork后,父子进程需【各自】返回一个。

循环创建n个子进程

一次fork函数调用可以创建一个子进程。那么创建N个子进程不能简单的以for(i = 0; i < n; i++) { fork() }来实现,因为产生子函数后,子函数会再次进入循环体调用fork函数,也就是子函数也会再创建自己的子函数,从而形成裂变,最终的子函数个数是(2^n)-1。

正确的创建n个子进程的写法如下:

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

#define CHILDNUM 5

int main(int argc, char **argv)
{
	int i = 0;
	for (i = 0; i < CHILDNUM; i++) {
		/* 如果是子进程,即fork返回值是0,则直接退出循环,
		 * 避免裂变 */
		if (fork() == 0)
			break;
	}

	if (i == CHILDNUM) {
		/* 父进程会进入此代码块,睡眠CHILDNUM秒,保证最后一个打印信息 */
		sleep(CHILDNUM);
		printf("I'm parent, pid = %d\n", getpid());
	} else {
		/* 子进程会进入此代码块,睡眠i秒再打印信息 */
		sleep(i);
		printf("I'm %dth child, pid = %d\n", i + 1, getpid());
	}
	return 0;
}

 

getpid函数

获取当前进程ID

pid_t getpid(void); 

 

getppid函数

获取当前进程的父进程ID

pid_t getppid(void);

 

getuid函数

获取当前进程实际用户ID

uid_t getuid(void);

获取当前进程有效用户ID

uid_t geteuid(void);

 

getgid函数

获取当前进程使用用户组ID

gid_t getgid(void);

获取当前进程有效用户组ID

gid_t getegid(void);

 

进程共享

父子进程之间在fork后。有哪些相同,那些相异之处呢?

刚fork之后:

父子相同处: 全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式...

父子不同处: 1.进程ID   2.fork返回值   3.父进程ID    4.进程运行时间    5.闹钟(定时器)   6.未决信号集

似乎,子进程复制了父进程0-3G用户空间内容,以及父进程的PCB,但pid不同。真的每fork一个子进程都要将父进程的0-3G地址空间完全拷贝一份,然后在映射至物理内存吗?

当然不是!父子进程间遵循读时共享写时复制的原则。这样设计,无论子进程执行父进程的逻辑还是执行自己的逻辑都能节省内存开销。  

 

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

int var = 10;

int main()
{
	pid_t pid = 0;
	pid = fork();
	if (pid == -1) {
		perror("fork");
		return -1;
	} else if (pid > 0) {
		/* 父进程 */
		sleep(1);
		var = 20;
		printf("I'm parent, pid = %d, parentID = %d, var = %d\n", getpid(), getppid(), var);
	} else if (pid == 0) {
		/* 子进程 */
		var = 30;
		printf("I'm child, pid = %d, parentID = %d, var = %d\n", getpid(), getppid(), var);
	}
	printf("var = %d\n", var);
	return 0;
}

 

重点注意!躲避父子进程共享全局变量的知识误区!

父子进程共享:1. 文件描述符(打开文件的结构体)  2. mmap建立的映射区

特别的,fork之后父进程先执行还是子进程先执行不确定。取决于内核所使用的调度算法。

 

---------------

我是良许,世界500强外企 Linux 开发工程师,专业生产 Linux 干货。欢迎关注我的公众号「良许Linux」,回复「1024」获取最新最全的技术资料,回复「入群」进入高手如云技术交流群。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux应用编程 的相关文章

  • ssh 连接超时

    我无法在 git 中 ssh 到 github bitbucket 或 gitlab 我通常会收到以下错误消息 如何避免它 输出 ssh T email protected cdn cgi l email protection i ssh
  • 为什么 Linux 原始套接字的 RX 环大小限制为 4GB?

    背景 我试图mmap 我的原始套接字的 RX 环形缓冲区64 bitLinux 应用程序 我的环由 4096 个块组成 每个块大小为 1MB 总共 4GB 请注意 每个 1MB 块中可以有许多帧 如果您好奇 请参阅此文档了解背景信息 htt
  • Google BQ:运行参数化查询,其中参数变量是 BQ 表目标

    我正在尝试从 Linux 命令行为 BQ 表目标运行 SQL 此 SQL 脚本将用于多个日期 客户端和 BQ 表目标 因此这需要在我的 BQ API 命令行调用中使用参数 标志 parameter 现在 我已经点击此链接来了解参数化查询 h
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • 如何在 Ubuntu 中创建公共 HTML 文件夹?

    简单的问题 但由于某种原因我无法在谷歌上找到确切的答案 我在 Slicehost 上安装了全新的 Ubuntu 并且想在我的主目录中为包含一堆静态 HTML 文件的简单网站创建一个公共目录 我该怎么做呢 只是打字的问题吗mkdir publ
  • GMail 421 4.7.0 稍后重试,关闭连接

    我试图找出为什么它无法使用 GMail 从我的服务器发送邮件 为此 我使用 SwiftMailer 但我可以将问题包含在以下独立代码中
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include
  • 使用循环在 C 中管道传输两个或多个 shell 命令

    我正在尝试执行ls wc l通过 C 语言程序 而不是使用命令行 这是我当前的工作代码 int main int pfds 2 pipe pfds pid t pid fork if pid 0 The child process clos
  • 如何获取 (Linux) 机器的 IP 地址?

    这个问题和之前问的几乎一样如何获取本地计算机的IP地址 https stackoverflow com questions 122208 get the ip address of local computer 问题 但是我需要找到一个的I
  • 内核的panic()函数是否完全冻结所有其他进程?

    我想确认内核的panic 功能和其他类似kernel halt and machine halt 一旦触发 保证机器完全冻结 那么 所有的内核和用户进程都被冻结了吗 是panic 可以被调度程序中断吗 中断处理程序仍然可以执行吗 用例 如果
  • 与 pthread 的进程间互斥

    我想使用一个互斥体 它将用于同步对两个不同进程共享的内存中驻留的某些变量的访问 我怎样才能做到这一点 执行该操作的代码示例将非常感激 以下示例演示了 Pthread 进程间互斥体的创建 使用和销毁 将示例推广到多个进程作为读者的练习 inc
  • 如何在 Linux 中使用 C 语言使用共享内存

    我的一个项目有点问题 我一直在试图找到一个有据可查的使用共享内存的例子fork 但没有成功 基本上情况是 当用户启动程序时 我需要在共享内存中存储两个值 当前路径这是一个char and a 文件名这也是char 根据命令参数 启动一个新进
  • Mac OS X 上的 /proc/self/cmdline / GetCommandLine 等效项是什么?

    如何在不使用 argc argv 的情况下访问 Mac OS X 上的命令行 在 Linux 上 我会简单地阅读 proc self cmdline or use GetCommandLine在 Windows 上 但我找不到 Mac OS
  • 为什么opencv videowriter这么慢?

    你好 stackoverflow 社区 我有一个棘手的问题 我需要你的帮助来了解这里发生了什么 我的程序从视频采集卡 Blackmagic 捕获帧 到目前为止 它工作得很好 同时我用 opencv cv imshow 显示捕获的图像 它也工
  • 在生产服务器上使用 Subversion 使文件生效的最佳方法是什么?

    目前我已经设置了 subversion 这样当我在 Eclipse PDT 中进行更改时 我可以提交更改 它们将保存在 home administrator 中项目文件 该文件具有 subversion 推荐的 branches tags
  • 如何在 *nix 中登录时运行脚本?

    我知道我曾经知道如何做到这一点 但是 如何在 unix 中登录时运行脚本 bash 可以 From 维基百科 Bash http en wikipedia org wiki Bash 28Unix shell 29 当 Bash 启动时 它
  • Linux/POSIX:为什么 fork() 不分叉*所有*线程

    众所周知 POSIX下创建新进程的默认方式是使用fork 在 Linux 下 这在内部映射到clone 我想知道的是 众所周知 当一个人打电话时fork 子进程是用单个线程创建的 调用的线程fork cf https linux die n
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • 使用os.execlp时,为什么`python`需要`python`作为argv[0]

    代码是这样的 os execlp python python child py other args this works os execlp python child py other args this doesn t work 我读过
  • 无法显示 Laravel 欢迎页面

    我的服务器位于 DigitalOcean 云上 我正在使用 Ubuntu 和 Apache Web 服务器 我的家用计算机运行的是 Windows 7 我使用 putty 作为终端 遵循所有指示https laracasts com ser

随机推荐

  • 【PASS】析因设计样本量计算

    b站视频 working
  • 软件设计和硬件开发 部分学习网站

    1 单片机教程网 http www 51hei com 2 博客园 https www cnblogs com 3 各种程序语言基础知识 https www runoob com cprogramming c scope rules htm
  • Linux运维基础--常见命令

    Linux运维基础 常见命令 linux的发行版本介绍 Linux 内核 kernel 版本主要有 4 个系列 分别为 Linux kernel 2 2 Linux kernel 2 4 Linux kernel 2 6 Linux ker
  • 贪心——字典序最小问题

    https vjudge net problem POJ 3617 题目简单理解就是 给定长度为N的字符串为S 要构造一个长度为N的字符串T 起初 T 是一个空串 随后反复进行下列任意操作 从S的头部删除一个字符串 加到T的尾部 从S的尾部
  • 教与学(TlBO)算法路径规划应用

    是一种基于群体的启发式优化算法 不需要任何算法特定参数 这种方法模拟了传统的课堂教学过程 整个优化过程包括教师阶段和学习者阶段 在教师阶段 每个学生都向最优秀的个体进行学习 在学习阶段 每个学生都以随机的方式向其他学生学习
  • k8s--基础--23.3--认证-授权-准入控制--授权

    k8s 基础 23 3 认证 授权 准入控制 授权 1 介绍 Kubernetes的授权是基于插件形式的 其常用的授权插件有以下几种 1 Node 节点认证 2 ABAC 基于属性的访问控制 3 RBAC 基于角色的访问控制 4 Webho
  • 在IDEA中用jdbc技术通过配置文件连接mysql数据库连接池

    File gt project Structure gt Libraries gt 点 号 gt java gt 选择在电脑中下载druid 1 1 9 jar及以上版本的德鲁伊jar包和mysql connector java 8 0 0
  • MySQL-锁详解

    锁 锁是计算机协调多个进程或线程并发访问某一资源的机制 在数据库中 除传统的计算资源 如CPU RAM I O等 的争用以外 数据也是一种供许多用户共享的资源 如何保证数据并发访问的一致性 有效性是所有数据库必须解决的一个问题 锁冲突也是影
  • 算法刷题-双指针-反转链表

    反转链表的写法很简单 一些同学甚至可以背下来但过一阵就忘了该咋写 主要是因为没有理解真正的反转过程 206 反转链表 力扣题目链接 题意 反转一个单链表 示例 输入 1 gt 2 gt 3 gt 4 gt 5 gt NULL 输出 5 gt
  • fork() 函数

    请问下面的程序一共输出多少个 int main void int i for i 0 i lt 2 i fork printf return 0 答案 8 解析 参考文章 https coolshell cn articles 7965 h
  • Ubuntu 18.04 安装Tensorflow遇到的问题

    问题一 Tensorflow安装完成后测试时 出现libcublas so 9 0找不到问题 ImportError libcublas so 9 0 cannot open shared object file No such file
  • uni-app 数据上拉加载更多功能

    实现上拉加载更多 打开项目根目录中的 pages json 配置文件 为 subPackages 分包中的商品 goods list 页面配置上拉触底的距离 subPackages root subpkg pages path goods
  • 线程的同步和互斥

    线程的同步和互斥题目 题目 设计生产者与消费者模型 缓冲区是一个大小为10的环 每个生产者产生一个0 1000的随机整数 存放在环空位中 消费者从环中取数据 并输出 一个生产者或消费者对应一个线程 要避免 1 两个生产者同时向环的同一个位置
  • 两个数组找相同元素_leetcode数组--sort排序题目汇总

    概要 此类题目的特点是会遇到一些杂乱无序的数组 经过排序后 会更好处理 1051 高度检查器 学校在拍年度纪念照时 一般要求学生按照 非递减 的高度顺序排列 请你返回能让所有学生以 非递减 高度排列的最小必要移动人数 注意 当一组学生被选中
  • qrcode页面生成二维码

  • 2.使用服务端SDK

    使用服务端SDK 一 服务端SDK 1 简介 2 功能介绍 二 使用SDK 1 安装 2 初始化 3 创建测试类 三 创建测试用例 1 获取视频播放凭证 2 获取视频播放地址 一 服务端SDK 1 简介 sdk的方式将api进行了进一步的封
  • 人工智能的道德与伦理

    人工智能的道德与伦理 对人工智能的研究始于上世纪50年代 近几年 科学界和产业界对它的兴趣超越了以往 最近一年半来 谷歌收购了十几家机器人公司 并正在开发人工智能的一个图腾 无人驾驶汽车 去年 社交媒体脸谱成立了新的人工智能实验室 数据显示
  • 技术架构演进之路-Docker【二】

    docker 技术架构演进之路 了解每种技术架构以及如何演进的 熟悉Docker在架构中的核心作用 八大架构演进 一 单机架构 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img 9o2adujk 168437644
  • vue axios全攻略

    不再继续维护vue resource 并推荐大家使用 axios 开始 axios 被越来越多的人所了解 本来想在网上找找详细攻略 突然发现 axios 的官方文档本身就非常详细 有这个还要什么自行车 所以推荐大家学习这种库 最好详细阅读其
  • Linux应用编程

    进程控制 fork函数 函数说明 创建一个子进程 函数原型 pid t fork void 返回值 失败返回 1 成功返回 父进程返回子进程的ID 非负 子进程返回 0 pid t类型表示进程ID 但为了表示 1 它是有符号整型 0不是有效