文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

聊聊 Linux 中进程与线程

2024-12-02 07:54

关注

线程

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。进程与线程之间的关系 同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。

linux中线程与进程

linux内核中,进程与线程它们虽然都是任务,但是应该加以区分。其中,pid 是 process id,tgid 是 thread group ID。任何一个进程,如果只有主线程,那 pid 是自己,tgid 是自己,group_leader 指向的还是自己。但是,如果一个进程创建了其他线程,那就会有所变化了。线程有自己的 pid,tgid 就是进程的主线程的 pid,group_leader 指向的就是进程的主线程。所以有了 tgid,我们就知道 tast_struct 代表的是一个进程还是代表一个线程了。关系如下:图片来源[1]

关于线程与进程的内核参数

ulimit 限制,在 Linux 下执行ulimit -a,你会看到 ulimit 对各种资源的限制。

其中的“max user processes”就是一个进程能创建的最大线程数,我们可以修改这个参数:

ulimit -u 66535

2.参数sys.kernel.threads-max限制。这个参数限制操作系统全局的线程数,通过下面的命令可以查看它的值。查看threads-max的方法:

cat /proc/sys/kernel/threads-max
32768

修改这个值的方法:

#方法一,重启后会失效
echo 65535 > /proc/sys/kernel/threads-max
#方法二,永久修改
echo "kernel.threads-max = 65535" >> /etc/sysctl.conf

3.参数sys.kernel.pid_max限制。这个参数限制操作系统全局的线程数,通过下面的命令可以查看它的值。这里说一下32位操作系统这个值最大是32768不能修改,64位系统上pid_max最大值为2^22。Linux 内核在初始化系统的时候,会根据机器 CPU 的数目来设置 pid_max 的值。比如说,如果机器中 CPU 数目小于等于 32,那么 pid_max 就会被设置为 32768(32K);如果机器中的 CPU 数目大于 32,那么 pid_max 就被设置为 N*1024 (N 就是 CPU 数目)。查看pid_max的方法:

cat /proc/sys/kernel/pid_max
32768

修改这个值的方法:

#方法一,重启后会失效
echo 65535 > /proc/sys/kernel/pid_max
#方法二,永久修改
echo "kernel.pid_max = 65535" >> /etc/sysctl.conf

注意:一个线程数也会占用一个pid,所以threads-max须要小于等于pid_max。

容器线程数量的限制

对于 Linux 系统而言,容器就是一组进程的集合。如果容器中的应用创建过多的进程或者出现 bug,就会产生类似 fork bomb 的行为。这样,不但会使同一个节点上的其他容器无法工作,还会让宿主机本身也无法工作。所以对于每个容器来说,我们都需要限制它的最大进程数目,而这个功能由 pids Cgroup 这个子系统来完成。之前遇到过这样一个问题,java应用因为要处理很多定时任务,一个定时任务拉起一个线程。但是由于代码上的 bug ,没有及时对线程进行回收,然后这个容器不断产生线程,耗尽了宿主机的进程表空间,最终导致整台linux上的服务报错“java.lang.OutOfMemoryError: Unable to create native threads”,影响了其它的服务。创建进程出现“Resource temporarily unavailable”的报错。这种问题除了让开发人员修复 bug 外,也需要在系统层面对线程数量进行限制。

cgroup

cgroup中对pid进行了隔离,通过更改docker/kubelet配置,可以限制pid总数,从而达到限制线程总数的目的。

docker,容器启动时设置 --pids-limit 参数,限制容器级别pid总数

kubelet,开启SupportPodPidsLimit特性,设置–pod-max-pids参数,限制node每个pod的pid总数

原理如下:在一个容器建立之后,创建容器的服务会在 /sys/fs/cgroup/pids 下建立一个子目录,就是一个控制组,控制组里最关键的一个文件就是 pids.max。kubelet或者docker向这个文件写入数值,而这个值就是这个容器中允许的最大进程数目。Kubernetes 里面的每个节点都会运行一个叫做 Kubelet 的服务,负责节点上容器的状态和生命周期,比如创建和删除容器。根据 Kubernetes 的官方文档 Process ID Limits And Reservations 内容,可以设置 Kubelet 服务的 –pod-max-pids 配置选项,之后在该节点上创建的容器,最终都会使用 Cgroups pid 控制器限制容器的进程数量。

总结

linux中为了防止进程恶意使用资源,系统使用ulimit来限制进程的资源使用情况(包括文件描述符,线程数,内存大小等)。同样地在容器化场景中,需要限制其系统资源的使用量。pid是计算机重要资源,所以需要在使用时,加以限制,以保证资源的合理利用。dockerd暂无默认的pid limit设置;k8s 限制线程数,可通过在kubelet中开启SupportPodPidsLimit特性,设置pod级别pid limit。

好了,今天的内容就到这里。我是夏老师,祝你今天知识吃饱,我们下次再见。


来源:运维开发故事内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯