进程
1.程序和进程
程序:是保存在磁盘上实现了某个功能的代码模块,包含代码逻辑和数据,没有运行的概念,是静态的。
进程:是程序的一次动态执行过程,进程是程序执行和资源管理的最小单位。是动态的包含代码逻辑,数据,系统资源。
2.进程的标识
进程号pid:唯一标识一个进程的符号 ps-aux
父进程号ppid:标识当前进程父进程的符号
将一个程序放到操作系统中,该程序就变成了一个进程,操作系统为该进程分配一个task_struct来标识它,同时分配4G虚拟的内存空间。
进程=task_struct+4G(虚拟内存)
linux系统中的task_struct是PC的一种,是一个描述进程的结构体。主要的内容有:
标识符--》pid
状态
优先级
程序计数器(pc)
内存指针
3.进程类型
linux系统中的进程类型
1)交互进程:给指令有回应的进程 ps ls
2)批处理进程:是一个进程的集合,维护者一个进程列队,负责按顺序启动列队中的进程。 shutdown -h down
3)守护进程:周期性的执行某项任务或等待某个事件发生的进程,不依赖shell终端,生存周期较长(从开机开始到关机结束)
守护进程的创建
1)创建一个子进程,让父进程退出(fork)
2)创建新的会话期setsid()
3)改变进程的工作目录chdir(“/”)
4)取消文件的权限掩码umask(0)
5)关闭所有文件描述符getdtablesize
4.进程相关指令
ps -aux(查看系统中运行的程序), ps -axj(查看系统中运行的程序),
top(动态查看进程), pstree(查看进程树), kill(关闭一个进程 kill -9 进程号),nice(以指定的优先级运行进程 nice -20 ./a.out<-20最高-19最低>),
renice(改变正在运行的程序的优先级)。
5.进程的状态(linux系统中有三种状态)可以相互切换
运行态 等待态 停止态(kill -stop pid)
6.进程的启动方式
1)手工启动:ls -l ./a.out
2)调度启动;/etc/init.d/rcS-->自动启动某些应用程序,
at:在一个指定的时间执行一个任务at 12:00 shutdown -S -T30
7.进程相关函数
1)fork作用:创建一个子进程(创建方式:子进程复制了父进程的所有内容,它和父进程的进程号不同)
无入参
返回值:创建失败 -1; 创建成功 0或者pid( 0->子进程子进程的进程号pid->父进程)
孤儿进程:父进程先于子进程退出,子进程由init进行收养,此时的子进程就是孤儿进程,pstree查看。孤儿进程可单独存在没有危害
僵尸进程:子进程先于父进程退出,父进程未处理子进程的退出状态,导致该进程成为一个僵尸进程,僵尸进程占用一个task_struct,但是没有相应的地址空间,它会统一参与操作系统的调度,会消耗系统资源,对系统有危害,我们应当避免僵尸进程的产生。ps -aux查看
excel函数子族:用来替换进程(六个函数作用相同,传参方式不同。传参方式由l v p e组合而成)
l:list以列表的方式传参,最后以NULL结束
v:vector以数组方式传参,数组的最后一个元素为NULL
e:env环境变量,传参方式同数组
p:PATH,在PATH所指的路径中去找可执行程序
exit / _exit
exit:退出当前进程,并刷新io缓存区 参数1:表示退出状态值。0表示正常输出,其他为异常退出
_exit:退出当前进程,不会刷新io缓存区
wait/waitpid
wait:等待子进程退出(任意子进程),接收子进程的退出状态值pid_t wait(int *status) *status:指向等到的子进程的退出状态值的指针 返回值:>0 等到的子进程的pid -1出错 注意:wait是一个阻塞函数。
阻塞函数:未等到结果,不返回会一直阻塞当前进程,直到等到结果再返回。
为等到结果,也返回不影响当前进程的执行,通过多次循环调用非阻塞函数去等结果。
waitpid:等待指定子进程的退出状态值,接收子进程的退出状态值 pid_t waippid(pid_t pid,int *status,int options)
pid:指定进程的pid
*status:指向等到的子进程的退出状态值的指针 options:0:将waitpid函数变成阻塞函数 WNOHANG:将waitpid函数变成非阻塞函数未等到结果返回0.
2.线程相关
1)定义:线程是一种轻量级的进程,用task_struct来标识它,它没有自己独立内存空间空间的
2)创建线程 使用第三方线程库提供的API
void *(*start_routine) (void *), void *arg);
作用:创建一个线程
*thread:指向线程ID的指针
*attr:线程属性,通常给NULL
参数三:指向线程执行函数的函数指针
*arg:传给线程执行函数的入参
返回值:0 成功;非0 失败
int pthread_join(pthread_t thread, void **retval);
作用:阻塞等待线程结束,并回收状态值
thread:线程ID
**retval:指向线程退出状态值的指针
void pthread_exit(void *retval);
作用:线程退出函数
*retval:线程退出状态值
int pthread_cancel(pthread_t thread);
作用:取消线程
thread:线程ID
3)多线程的通信 同步 互斥(在一个进程中可以创建多个线程,那么多个线程间会存在数据通信问题,
会存在两个线程相互配合完成一件事情,会存在两个线程对公共资源的竞态访问问题)
多线程的数据通信--》使用全局变量
./pthead_com1 hello
4.2多线程的同步-->无名信号量 sem_t sem;
同步:两个线程按照一定的顺序相互配合完成一件事情
pthread1-->hello 1S sem_t sema;-->P/V操作函数控制sema和semb
pthread2-->world 1s sem_t semb;
P操作:sem_wait(&sema)
含义:sem_wait会检测信号量sema的值是否大于0,若大于0,将sema减一
同时函数返回。若等于0,阻塞当前线程。
V操作:sem_post(&sema)--》非阻塞函数
含义:sem_post只会给检测的信号量sema加1