进程:
什么是进程?为什么要学进程?
阻塞的概念…………………….标准IO流中等待获取信息,,,,等待就是阻塞!
嵌入式设备---------数据的采集
如何创建进程??
程序:是静态的,程序的运行-à进程。
进程----它是一个程序的实例; 进程--à①---à②<-----线程--à调度
①资源的分配 进程是程序执行和资源分配的最小单位
②进程描述符(tast_struct) 结构体----用来描述一个进程
sizeof(tast_struct) -----1.7k
③线程 (内核调度的最小单位) 内核怎么执行它? current 指向当前需要执行的进程。。。。。
④调度
进程 程序
文本段 text 二进制指令集的结合(文本段)
数据段data 文本段text------数据段(全局段)
堆栈段stack(局部变量,回调关系)文本段—自读数据,而数据段为可读写数据
数据段:存放的是全局变量、常数以及动态分配数据分配的空间(malloc)
文本段:存放程序中的代码。
堆栈段:存放的是函数返回的地址,函数的参数以及程序中的局部变量。
进程ID
task_struct 中存在一个进程号PID,为用户提供找到tast_struct这结构体,另外还有一个parent指向tast_struct,不能给用户和直接操作,所以又提供另一PPID父进程号。。。。
ps -ef 查看进程号
pid = getpid()对于每个进程来说都是唯一的。。。 ppid = getppid()
init 一号进程,这个一号进程能够获得什么东西呢???孤儿进程的回收站
init是内核启动到最后阶段,自动执行的。。。。。init创建一个tast_struct去执行其它程序。。。
linux系统中的进程类型:
① 交互式进程:由shell控制和运行的。。
②批量出路进程 很少使用
③守护进程:该程序在后台运行,其次它与所有终端都无关,一般在linux启动时开始执行,系统关闭的时候才结束。。。
进程的运行状态:
①运行态:此时进程或者在运行或在准备运行
②等待态:
可中断------不可中断
③停止态:进程终止。。。。。。debug时。。。。
④死亡态:也叫僵尸态。子进程退出,但是父进程没退出,此时的子进程就是僵尸态。。。子进程的状态不会被系统回收,它需要父进程回收。。。。注意:父进程必须及时注意回收子进程,以免内存泄露
进程的模式:
①3G 大小的 用户空间 用户模式 只能通过系统调用(system call)来操作内核
②1G 大小的 内核空间 内核模式 物理地址映射到虚拟空间的部分
6.32 位操作系统 拥有4G寻址空间
7.进程的一些命令:
ps 查看系统中的进程 -aux 显示详细信息 -ef
top 和 资源管理器相似。。。。。一直刷新显示不同的状态
注意:ps和top 依赖与/proc目录(proc文件系统),因为/proc是挂载点,掉电丢失。。。。/proc中每个数字都为一个进程号
nice (需要权限)按用户指定某种优先级来运行进程 nice --20 ./a.out & %100独占CPU(优先级的概念:高优先级的任务分配更多的时间片。。。。 抢占 :重新分配时间片 )
renice 改变正在运行进程的优先级 renice -19 PID号
kill 向一个进程发送一个信号 kill -l 可看到这些信号
例如:kill -9 PID号 向PID号的进程发送9这一信号(SIGKILL)
history | grep renice 查看历史renice信息
bg 将挂起(ctrl + z)的进程放到后台执行
fg 将最后挂起的进程重新放到前台运行
8. 创建一个进程: 目的,让两个人进程间有血缘关系,执行同一程序中的不同的代码部分。。。
fork() 没有参数。。。
注意:返回值,{-1 失败, 0 或者 > 0 成功}
调用一个fork()----即创建了2个进程。。。。 clone出一个父进程的子进程,即2相同的进程,执行相同的代码。fork执行的过程中即已经变为2个进程,同时向父进程返回一个大于0的号,向子进程返回一个0.。。。。。。。(父进程为什么要返回 > 0? 因为父进程有多个儿子。。。)
if(pid = = fork()<0) 理论上子进程先执行
exit -1;
if (pid > 0)
ppid; // 父进程
else if (pid == 0)
pid; // 子进程
9.vfork()与fork()的不同之处:数据共享----执行顺序------退出
①vfork不拷贝父进程的任何资源,但和父进程共享资源。。。。。
②vfork之后父进程停止,而先执行子进程,子进程执行完成后且调用exec或者exit(),然后才执行父进程。。。
即用vfork的主要目的是调用exec
子进程必须调用exec 或者exit(0)。。如果没有,则程序执行出现异常
当今的fork是写拷贝技术。。。。。。。。写拷贝技术????当数据需要用时才拷贝,否则不拷贝。。这样的好处就是,避免了vfork的数据共享,也避免了fork的全拷贝。。。。。。
10.exec函数族(有6个)
shell脚本--------C语言中
函数的作用:把当前进程作为一个容器,然后将另外一个程序的内容填充。。。。。所以,exec后的程序将不能执行。。。
注意:在使用exec函数族时,一定要加上错误判断语句。。。。。
if (execl(”/bin/ls”,”ls”,”-l”,NULL)< 0) // NULL是一个类似哨兵,必须有这个参数
{
perror(“execl\n”);
return -1;
}
11.完善man帮助包 。。。。有些man不出来
sudo apt-get install manpages-posix-dev
12.exit(status) #include<stdlib.h> 和 _exit(status) #include <unistd.h>
status是一个整型的参数,可以利用这个参数传递进程结束的状态。通常0表示正常结束;其他的数值表示出现错误。。。。
exit和_exit()的区别:
_exit()函数直接使进程停止运行,清除其使用的内存空间,并销毁其再内核中的各种数据结构;
exit()函数则在这些基础上作了包装,在调用exit系统之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,即“清理I/O缓冲”。。。注意换行‘\n’也会引起I/O的清理工作。。。。。
使用_exit退出,上一语句必须有’\n’换行符,才能够打印出语句。。。。
13.wait和waitpid
wait函数:只能父进程调用。。。。回收子进程的状态
waitpid 主要功能:回收子进程的状态。。。。 wait 是waitpid的一个特例。。。。。。
pid_t waitpid(pid,status,options)
参数:pid > 0,等待进程ID等于pid的子进程(指定ID)
pid = -1 等待任意一个子进程 (wait == waitpid(-1,status,0))
pid = 0
pid < -1
WNOHANG:
WUNHACED:
与进程相关的概念:
会话:每个用户登录一次,则开打一个会话
进程组:在终端上执行,则产生一个进程组
进程:
14.守护进程 dacmon 主要运用在网络服务中使用
一般是一些服务,常在系统启动时开始运行,系统关闭时终止。。
一般运行在后台,脱离终端,它不属于
ps -ef 查看。。。。名字后面带个d,都是守护进程
创建守护进程的步骤:
创建子进程,父进程退出
(第一步结束之后,子进程就在形式上与控制终端脱离,又由于负进程已经先于子进程退出,子进程变成了孤儿进程)
pid = fork();
if (pid >0)
exit(0);
在子进程中创建新的回话
(进程组是一个或者个进程的集合,进程组由进程组ID来唯一标识。没给进程组都有一个组长进程,进程组ID组长进程的进程号)
(会话组是一个或者多个进程组的集合。。。在子进程中创建新的会话,)
setsid();// 创建一个新的会话,并使得当前进程称为新会话组的组长。
//setsid函数能够使进程完全独立出来,从而脱离所有其他进程的控制。。。。。
改变工作的目录为目录
chdir(“/”);
重设文件权限掩码
umask(0);
关闭文件描述符
(新的进程会从父进程那里继承所有已经打开的文件。。。再创建完成新的会话之后,守护进程已经脱离任何控制终端,应当关闭用不到的文件)
close(fd);
实验例程:
查看系统环境变量
#include <stdio.h>
int main(int argc, char **argv, char **envp)
{
int i = 0;
while(envp[i] != NULL)
{
printf("%s\n", envp[i]);
i++;
}
return 0;
}