目录
案列1
地址空间:包括进程上下文、进程堆栈、打开的文件描述符、信号控制设定、进程优先级、进程组号等。子进程所独有的只有它的进程号,计时器等。因此,使用fork函数的代价是很大的。
案例15:验证execl返回值 (ps:注意路径的问题,只有在当前的路径才行)
好处:相比于system的好处就是,可以获取程序运行时的输出结果
1.进程的概念
1.1 进程的定义
程序:程序是存放在存储介质上的一个可执行文件。
进程:进程是程序的执行实例,包括程序计数器、寄存器和变量的当前值。
程序是静态的,进程是动态的
在 linux 系统中进程号(进程标识符)由 0 开始。
进程号为 0 及 1 的进程由内核创建。
进程号为 0 的进程通常是调度进程,常被称为交换进程(swapper)。进程号为 1 的进程通常是 init 进程。
除调度进程外,在 linux 下面所有的进程都由进程 init 进程直接或者间接创建。
1.2 在Linux系统中如何查看进程
ps命令、ps -aux命令


-------------------------------------------------------------------------------------------------------------------------------
查看特定的字段进程-----管道命令(grep)
grep init

-------------------------------------------------------------------------------------------------------------------------------
查看进程的占用率的情况----top命令

-------------------------------------------------------------------------------------------------------------------------------
进程号
每个进程都由一个进程号来标识,其类型为pid_t,进程号的范围:0~32767
进程号是由操作系统随机给当前进程分配的,不能自己控制进程号总是唯一的,但进程号可以重用。当一个进程终止后,其进程号就可以再次使用了
进程号(PID)
标识一个进程的非负整型数
父进程号(PPID)
任何进程(除 init 进程)都是由另一个进程创建,该进程称为被创建进程的父进程,对应的进程号称为父进
程号(PPID)。
进程组号(PGID)
进程组是一个或多个进程的集合。他们之间相互关联,进程组可以接收同一终端的各种信号,关联的进
程有一个进程组号(PGID) 。
Linux 操作系统提供了三个获得进程号的函数 getpid()、getppid()、getpgid()。
需要包含头文件:
1 #include <sys/types.h>
2 #include <unistd.h>
3 pid_t getpid(void);
4 功能:获取当前进程的进程号
5 pid_t getppid(void);
6 功能:获取当前进程的父进程的进程号
7 pid_t getpgid(pid_t pid);
8 功能:获取当前进程所在进程组的
案列1
#include <stdio.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4
5 int main(int argc, char const *argv[])
6 {
7 //获取当前进程的进程号
8 printf("pid = %d\n", getpid());
9
10 //获取当前进程的父进程的id
11 printf("ppid = %d\n", getppid());
12
13 //获取当前进程所在组的id
14 printf("pgid = %d\n", getpgid(getpid()));
15
16 while(1)
17 {
18
19 }
20
21 return 0;
22 }
运行结果:

案例2:查看进程中的PID号
#include<stdio.h>
#include<sys/tyoes.h>
#include<unistd.h>
int main()
{
pid_t pid;
pid = getpid();
prinf("my pid is = %d\n",pid);
while(2); //防止进程终止
return 0;
}
~
~
~
~
~
运行结果:

使用top查看进程占用率

结果:可以看到当前进程由于while一直循环未退出,导致进程占用率百分之百
2进程的创建
2.1 进程的创建 fork 函数
在 linux 环境下,创建进程的主要方法是调用以下两个函数:
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);pid_tvfork(void)
创建一个新进程
pid_t fork(void)
功能:
fork()函数用于从一个已存在的进程中创建一个新进程,新进程称为子进程,原进程称为父进程。
返回值:
成功:子进程中返回 0,父进程中返回子进程 ID。
失败:返回-1。
C程序的存储空间是如何分配

地址空间:
包括进程上下文、进程堆栈、打开的文件描述符、信号控制设定、进程优先级、进程组号
等。子进程所独有的只有它的进程号,计时器等。因此,使用fork函数的代价是很大的。
示意图(用fork函数的代价还是比较大的):

案例3:创建子进程(不区分父子进程 不推荐写)
#include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 int main(int argc, char *argv[])
5 {
6 //通过fork函数创建一个子进程
7
8 //注意:主要执行一次fork,就会在原有的进程基础上创建一个新的子进程
9 //而且如果fork之后不区分父子进程的代码区,则后面所有的代码都会执行
10 fork();
11 printf("hello world\n");
12
13 while(1)
14 ;
15 return 0;
16 }
hello打印两次,也就以为着fork函数创建了一个子进程

案例4:区分父子进程
#include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 int main(int argc, char *argv[])
5 {
6 //通过fork函数创建一个子进程7
#if 0
9 //注意:主要执行一次fork,就会在原有的进程基础上创建一个新的子进程
10 //而且如果fork之后不区分父子进程的代码区,则后面所有的代码都会执行
11 fork();
12 printf("hello world\n");
13
14 while(1)
15 ;
16 #endif
17
18 //通过fork函数的返回值来区分父子进程的独立的代码区
19 //父子进程是来回交替执行的,谁先运行,谁后运行是不确定的,不要认为父进程执
行完之后才会执行子进程
20 pid_t pid;
21
22 pid = fork();
23 if(pid < 0)
24 {
25 perror("fail to fork");
26 return ‐1;
27 }
28 else if(pid > 0) //父进程的代码区
29 {
30 while(1)
31 {
32 printf("parent: pid = %d, ppid = %d\n", getpid(), getppid());
33 printf("pid = %d\n", pid);
34 printf("this is a parent process\n");
35 sleep(1);
36 printf("****************\n");
37 }
38 }
39 else //子进程的代码区
40 {
41 while(1)
42 {
43 printf("son: pid = %d, ppid = %d\n", getpid(), getppid());
44 printf("this is a son process\n");
45 sleep(1);
46 printf("‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐\n");
}
48 }
49
50 return 0;
51 }

说明两个情况:1.上面的等号关系

最低0.47元/天 解锁文章
1009

被折叠的 条评论
为什么被折叠?



