美文网首页linux
linux中进程与线程

linux中进程与线程

作者: 前浪浪奔浪流 | 来源:发表于2022-03-10 11:16 被阅读0次

进程

进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。进程的概念主要有两点:

第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。

第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操作系统执行之),它才能成为一个活动的实体,我们称其为进程。

线程

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在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 代表的是一个进程还是代表一个线程了。关系如下:

image.png

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

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

image.png

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

ulimit -u 66535

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

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

修改这个值的方法:

#方法一,重启后会失效
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。

相关文章

  • Linux内核设计与实现 进程管理2:进程、线程创建

    进程与线程的关系 在Linux中,没有线程这个概念。内核将线程与进程一视同仁,也就是说线程相当于一个标准的...

  • 你知道Linux并发与同步嘛?

    典型的UNIX系统都支持一个进程创建多个线程(thread)。 Linux以进程为单位组织操作,Linux中的线程...

  • 2019-06-03 Linux多线程

    Linux 多线程 线程是进程中负责程序执行的执行单元,一个进程至少有一个线程。进程有自己独立的资源,线程共享进程...

  • linux多进程与多线程

    linux多进程与多线程。 一,线程与进程的对应关系 先回答一个大家比较关心的问题,就是线程和进程的对应关系。 第...

  • task_struct结构

    进程标识符(PID) Unix系统通过pid来标识进程,linux把不同的pid与系统中每个进程或轻量级线程关联,...

  • Android中进程和线程

    1,Linux中的进程管理1)进程和线程进程是资源分配的最小单位。线程是操作系统调度执行的最小单位。进程和线程是程...

  • 进程管理

    进程管理进程和线程图形简单解释进程和线程管理VIM编辑Linux 系统资源信息的获取获取 Linux CPU 信息...

  • 浅谈linux线程模型和线程切换

    本文从linux中的进程、线程实现原理开始,扩展到linux线程模型,最后简单解释线程切换的成本。 刚开始学习,不...

  • Linux进程与线程

    1. 定义 进程(英语:process),是计算机中已运行程序的实体。线程(英语:thread)是操作系统能够进行...

  • 开题

    linux 内核 线程和进程管理

网友评论

    本文标题:linux中进程与线程

    本文链接:https://www.haomeiwen.com/subject/gssfdrtx.html