Linux 进程基础

PCB

PCB(进程描述符)位于内核空间中,每个进程的PCB是不同的,PCB是一个task_struct[1]结构体包括:

  • 进程id。每个进程都有一个唯一id,类型为pid_t(非负整数)。

  • 进程状态。就绪、运行、阻塞、停止。

  • 进程切换时需要保存和恢复的CPU寄存器。

  • VM与PM的映射,由MMU转化,保存在PCB中。

  • 当前工作目录。

  • umask掩码,提供文件权限相关。

  • 文件描述符表。

  • 信号相关信息。

  • 用户id和组id。

在这里插入图片描述

进程控制

fork函数

FORK(2)                        Linux Programmer's Manual                        FORK(2)

NAME
       fork - create a child process

SYNOPSIS
       #include <unistd.h>

       pid_t fork(void);

DESCRIPTION
       fork()  creates  a  new  process  by  duplicating  the calling process.  The new
       process is referred to as the child process.  The calling process is referred to
       as the parent process.
RETURN VALUE
       On success, the PID of the child process is returned in the  parent,  and  0  is
       returned  in  the  child.   On  failure,  -1 is returned in the parent, no child
       process is created, and errno is set appropriately.

返回值有两个,大于0代表父进程,等于0代表子进程(子进程成功被创建)。

创建一个子进程
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
	pid_t pid;
	
	printf("======before======\n");
	
	pid = fork();
	
	if (pid == -1) {
		printf("fork error");
		exit(1);
	} else if (pid == 0) {
		printf("===child, pid = %u, ppid = %u\n", getpid(), getppid());
	} else {
		printf("===parent, pid = %u, ppid = %u\n", getpid(), getppid());
		sleep(1);
	}
	
	printf("======after======\n");
	return 0;
}
~# ./test
======before======
===parent, pid = 9215, ppid = 8980
===child, pid = 9216, ppid = 9215
======after======
======after======
循环创建n个子进程
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
	pid_t pid;
	int n = 5;
	printf("======before======\n");
	
	int i;
	for (i = 0; i < n; i++) {
		pid = fork();
		if (pid == -1) {
			printf("fork error");
			exit(1);
		} else if (pid == 0) {
			//printf("===child, pid = %u, ppid = %u\n", getpid(), getppid());
			//如果是子进程的话,直接跳出循环~
			break;
		} else {
			//只有父进程继续执行 创建子进程
		}
	}
	
	if (i < n) {
		printf("child %dth, pid = %u, ppid = %u\n", i + 1, getpid(), getppid());
	}

	return 0;
}
~# ./test
child 5th, pid = 9345, ppid = 1
child 4th, pid = 9344, ppid = 1
child 3th, pid = 9343, ppid = 1
child 2th, pid = 9342, ppid = 1
child 1th, pid = 9341, ppid = 1

进程共享

fork之后

共享:全局变量、.data、.text、栈、堆、…

不共享:进程ID,fork返回值,父进程ID,进程运行时间,定时器,未决信号集。

fork之后

共享:文件描述符和mmap建立的映射区。

注意:全局变量也不会共享的。

父子进程遵循读时共享写时复制原则。

参考

[1] https://elixir.bootlin.com/linux/v4.1.15/source/include/linux/sched.h#L1292

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值