聊聊Linux下fork与线程池

本文介绍了Linux下的线程池概念及其优点,详细解析了Linux线程创建过程,并探讨了fork、孤儿进程与僵尸进程,以及如何解决僵尸进程。此外,还讨论了copy on write技术和vfork的特性及其使用注意事项。
摘要由CSDN通过智能技术生成

前言

这个知识点也是老生常谈了,咱们今天就把他讲清楚弄明白。

线程池

线程池是指在一个多线程程序中创建一个线程集合,在执行新的任务的时候不是新建一个线程,而是使用线程池中已创建好的线程,一旦任务执行完毕,线程就会休眠等待新的任务分配下来。
这么看来,线程池的优点就很明显了,在频繁的线程切换环境中,线程池可以省去多次线程的创建与释放所需要的时间。

Linux下的线程是如何创建的?

这个我还是稍微了解一点的。创建一个线程非常简单。
1.向内核空间申请一段内存用来存放新线程的PCB;
2.PCB中预留指针指向内核栈;
3.PCB中存放待执行线程函数与函数参数;
4.加入进程调度队列或直接ret执行(需要先将函数指针放在栈顶,然后ret会将其加载到eip寄存器上,完成立刻执行线程操作)

fork

简言之,fork就是创建了一个父进程的拷贝。
使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。
子进程与父进程的区别在于:
1、父进程设置的锁,子进程不继承(因为如果是排它锁,被继承的话,矛盾了)
2、各自的进程ID和父进程ID不同
记住,fork是一次调用两次返回值,因为会在两个地址空间中都执行返回。
如果成功创建一个子进程,对于父进程来说返回子进程ID
如果成功创建一个子进程,对于子进程来说返回值为0
如果为-1表示创建失败。
fork系统调用复制产生的子进程与父进程(调用进程)基本一样:代码段+数据段+堆栈段+PCB,当前的运行环境基本一样,所以子进程在fork之后开始向下执行,而不会从头开始执行。

孤儿进程与僵尸进程

fork系统调用之后,父子进程将交替执行,执行顺序不定。
如果父进程先退出,子进程还没退出那么子进程的父进程将变为init进程(托孤给了init进程)。(注:任何一个进程都必须有父进程)
如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵进程(僵尸进程:只保留一些退出信息供父进程查询)。僵尸进程可以在进程列表中查看。

Linux如何查看进程状态呢?

ps指令了解一下?process state。多的咱就不说了,百度上多得是介绍。

孤儿进程与僵尸进程的危害

首先任何进程都有父进程(init进程是所有进程的祖宗,它没有爸爸),当父进程抛弃了自己fork出来的子进程而执行完成后,子进程就被托管给init进程。
孤儿进程其实没啥危害。
僵尸进程就不一样了。本来吧,父进程在fork一个子进程的时候,接下来需要wait操作等待子进程结束,然后子进程才会全部释放资源(子进程执行完成后并没有全部释放资源,还剩下PID这种东西,退出状态这种东西,必须要父进程wait索取才会释放)。这下好了,父进程直接没wait就退出了,于是僵尸进城产生后,这个进程ID就再也不能被后续使用了。

如何解决僵尸进程

很简单,第一个是signal(可能有的朋友不了解什么是signal)。Linux的信号机制就提供了其中一种专门用来处理子进程退出问题的,叫SIGCHLD,写法也非常简单:

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <signal.h>

static void sig_child(int signo);

int main()
{
   
    pid_t pid;
    //创建捕捉子进程退出信号
    signal(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值