先来针对我们昨天进程遗留的一些补充的函数接口:
昨天了解到了三个进程中的函数接口:
分别是:
1.fork:创建子进程(具有异步特性)
2.getpid:获得当前进程的PID
3.getppid:获得创建当前进程的进程的PID
接下来我们来了解一下其他的进程中的函数接口:
4.exit
原型:void exit(int ststus)
功能:让进程结束
在主函数中调用exit与调用return效果相同:
5._exit:
原型:void _exit(int status)
功能:让进程结束
区别:
exit:
刷新缓存区,执行一系列进程,退出注册操作,最后让进程结束
_exit
不会刷新缓存区,直接让程序结束
6.wait(具有同步作用)
pid_t wait (int *wstatus)
功能:
回收子进程空间
参数:
wstatus:存放子进程结束状态空间的首地址
返回值:
成功时返回回收到的子进程的PID
失败时返回-1
wait:具有阻塞功能,子进程没结束,父进程阻塞子进程结束,回收子进程空间
判断子进程结束状态的宏
WIFEXITED(wstatus):判断子进程是否正常退出
WEXITSTATUS(wstatus):获得子进程结束时的值
WIFSIGNALED(wstatus):判断子进程是否被信号杀死
WTERMSIG(wstatus):获得杀死子进程信号的值
WCOREDUMP(wstatus):判断子进程是否段错误退出
WIFSTOPPED(wstatus):判断子进程是否被停止
WSTOPSIG(wstatus):获得停止子进程的编号
WIFCONTINUED(wstatus):判断进程是否继续执行
7.waitpid
pid_t waitpid(pid_t pid,int *wstatus,int options)
功能:
pid:回收子进程的id号,-1表示任意子进程
wstatus:存放子进程结束状态空间的首地址
options:
0:阻塞回收
WNOHANG: 非阻塞回收
返回值:
成功时返回回收到的子进程的pid
失败时返回-1
如果WNOHANG设置,没有子进程结束,返回0
wait(NULL) == wait(-1,NULL,0)
7.进程的消亡:
1.僵尸态进程代码如何产生:
进程代码执行结束,但是空间没有被回收
2.如何避免产生僵尸过程:
1.让父进程先结束,子进程称为孤儿进程,孤儿进程会被init进程收养,子进程结束,init回收子进程空间,避免产生僵尸进程
2.子进程结束,父进程回收子进程空间,避免产生僵尸进程,根据子进程结束的返回值判断出错与结束的信息
8.exec函数族
带p的是在PATH系统路径下查找
int execl(const char *path, const char *arg, ... (char *) NULL );
int execlp(const char *file, const char *arg, ...(char *) NULL );
int execle(const char *path, const char *arg,···, (char *) NULL, char * const envp[] );
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
功能:
利用进程空间执行另外的一段代码
- fork :创建新的子进程任务
- exec:执行另外的程序代码
在子进程中传参的类型:
l: 参数以列表形式传递
v: 参数以指针数组形式传递
p:在环境变量下PATH对应的目录下找file
e:更新进程的环境变量
对于进程的补充我们就到此结束了,接下来我们来了解一下什么是线程:
线程:
1.线程的概念:
线程就是轻量级的进程;
2.进程与线程的区别:
- 进程的空间是各自独立的
- 线程的空间位于进程空间的内部,一个进程的每个线程独享栈区的一部分,共享文本区,数据区,堆区
- 进程是操作系统资源分配的最小单元
- 线程是cpu任务调度的最小单元
3.线程的创建:
每个线程都会创建一个属于该线程的独立的栈区空间,默认为8m,文本区,数据区,堆区共用进程中的区域;
4.线程的调度:
等同于进程的调度:
宏观并行,微观穿行:
5.线程的消亡:
6.多进程与多线程的优缺点:
安全性方面:
- 每个进程空间独立,安全性好,一个进程异常崩溃,不影响其余进程
- 线程位于进程空间中,线程异常崩溃会导致进程崩溃,进程中其余的线程均结束
执行效率方面:
- 多进程进行调度,效率较低,因为切换进程任务时需要映射不同的物理地址空间,增大系统开销
- 多线程进行调度,效率高,因为是在同一进程空间内部切换不同任务
通信方面:
- 多进程通信不方便,因为不同进程空间独立,没有共享空间
- 多线程通信十分方便,多线程数据区,堆区共享
资源竞争方面:
- 进程不用考虑资源竞争问题,因为没有共享空间
- 需要通过锁的机制防止资源竞争:
7.线程相关函数接口:
1.pthread_create
原型:int pthread_create(pthread_t *thread,const pthread attr_t *attr,void *(star_routine)(void *),void *arg);
功能:创建一个线程任务;
参数:
thread:存放线程id空间的首地址;
attr :线程的属性,使用默认属性时直接传NULL;
star_routinue :线程函数入口;
arg:线程函数参数;
返回值:
成功返回0;
失败返回非0;