linux上可以运行多少进程 && 一个进程可以开辟多少线程?

本文探讨了Linux系统上可以运行的进程数量及其限制,通常由系统资源决定,可通过特定命令查看。对于一个进程,可以开辟的线程数量受限于调用栈大小,一般在300左右。可以通过调整系统参数进行一定的扩展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux上可以运行多少进程 && 一个进程可以开辟多少线程?

 

这个问题我们被困扰了很久,只知道一个大致数字,而没有很准确的结果,今天我们就自己测试一下?

首先我们需要了解:

  • 进程:是系统分配资源的单位,是运行中的程序,是程序+指令+资源的一组集合。
  • 线程:是cpu调度执行的最小单位,可以看作轻量级进程,线程是进程中的一条执行序列,我们可以通过线程库创建线程

 

我们可以想到,进程既然是系统分配资源的单位,那么当然会有一个数量限制,系统的资源也不是无限的,那么线程同理,线程是进程的一条执行序列,那么当然也会有一个数量限制了。

 

我们直接进入正题,一个一个解决:

第一个问题:linux上可以运行多少进程?

①:我们可以通过特定命令在Linux上查看一下系统的进程限制

 

可以看到,我自己linux系统上上限设置的是1024个,也就是说我的计算机上最多可以有1024个进程,但是这是一个软限制,是可以进行修改的,比如我们可以通过ulimit -u 4096来设置为4096个:

 

②:我们也可以通过pid的大小限制来判断一个进程的数量范围

我们在上一篇博客中探讨过,pid是一个短整型short,这个值的大小为PID_MAX,也就是32767,其中0~299是为系统进程(包括内核线程)保留的。

我们可以通过命令进行查看:

当然,这里数字只是表示理论上的限制,但是由于现实中计算机内存等系统资源的限制,是根本不会有这么多的进程同时打开的。

 

 

第二个问题:linux上一个进程可以开辟多少线程?

①:我们知道线程除了调用栈是自己独有的,其他的资源全部共享进程,所以限制一个进程可以开辟线程的数量的关键点就在于这个调用栈上。

我们可以通过命令查看一下系统会为一个线程调用栈分配多少资源:

 

我们可以看到结果是10240,单位是kbytes,表示线程调用栈大小为10M,而我们知道32位操作系统4G虚拟内存空间中除了1G内核空间还有3G的用户空间,所以一个进程可以开辟的线程数目就是用3G/10M,结果大致是300左右,但是实际上会比这个数字小一些,因为不能用户空间全部分配给你,肯定还有其他进程需要资源。

当然,我们可以通过ulimit -s来设置stack size,将10M变小一些就可以开辟更多的线程了。

 

②:我们通过代码自己进行测试一番,看到底能开辟多少线程

代码如下:

#include <stdio.h>
#include <pthread.h>
#include <assert.h>

void* func(void *arg)
{
}

int main()
{
	int i = 0;
	pthread_t id;

	while(1)
	{
		int res = pthread_create(&id, NULL, func, NULL);
		if(res != 0)
		{
			break;
		}
	
		printf("已开辟线程数:%d\n", i++);
	}
	return 0;
}

 

我们可以看到测试结果为301个:

 

符合上述预估的值,我们计算机也就大致开辟300左右的线程。

Linux系统支持多种进程间通信(IPC,Inter-Process Communication)以及线程间通信的方式。理解这两者的区别及其实现机制对于编写高效的并发程序至关重要。 ### 进程间通信 1. **管道(Pipe)**:最简单的形式之一,适用于有亲缘关系的两个进程之间进行单向数据传递。匿名管道仅限于父子进程间的通讯;命名管道则可以跨越无血缘关系的进程。 2. **消息队列(Message Queue)**:允许一个或多个进程将信息发送到另一个进程中存储的消息列表里,并从该列表读取消息。它具备更强的功能性和灵活性比普通文件更高效地处理小块的数据交换任务。 3. **信号量(Semaphore)** 和**共享内存(Shared Memory)**: - *信号量*用于控制对资源访问权限的数量限制,保证同步协调工作。 - *共享内存段*提供了一种快速存取大容量数据的有效途径,使得不同进程可以直接操作共同开辟的一片虚拟地址空间内的内容。 4. **套接字(Socket)**:不仅能在本地机器的不同应用程序间建立连接,而且能通过网络与其他计算机上运行的服务端口相互通信,是最具通用性的跨平台方案。 5. **信号(signal)**:主要用于通知接收方发生了某些特定事件,比如用户按键中断、硬件错误等非正常情况下的即时反馈机制。 --- ### 线程间通信 在同一进程中创建出来的各个线程由于共享相同的上下文环境(包括全局变量表、堆栈指针寄存器值),因此它们之间的交互更为直接紧密: 1. **互斥锁(mutex lock)** 及其他类型的 锁结构 :如读写锁(read-write locks),条件变元(condition variables) ,自旋锁(spinlocks), etc., 主要是用来解决临界区竞争问题,即当多个线程试图同时修改同一份数据时如何确保一致性。 2. **事件(event signaling)** 或者说是基于等待唤醒模式的工作流设计,在某个条件下让某几个指定的参与者得到提示继续前进而不再阻塞下去。 3. **原子操作(atomical operations)**:在现代多核处理器架构下提供的底层汇编指令级的支持功能,能够一次性完成增减计数器之类的简单动作而不必担心中途被打断造成混乱局面发生。 总之,无论是选择哪种方式进行交流沟通都应当考虑到效率损耗成本、可移植性因素等方面的影响做出合理决策。 --
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值