进程 线程 协程

本文深入探讨了进程、线程和协程的概念及其在Linux系统中的实现方式。阐述了进程作为资源分配单位,线程作为调度单位的角色,以及协程在用户态自我调度的特点。分析了Linux中线程(轻量级进程)和内核线程的创建过程及区别,揭示了协程的轻量化优势。
摘要由CSDN通过智能技术生成

进程 线程 协程


进程 线程 协程,网上资料繁多,有些是个人理解,存在一定误导性。

操作系统 考试经常会考:进程是资源的分配单位,线程是调度单位;进程切换开销大、线程切换开销小等等。网上经常会说协程就是线程等等,在linux 的世界里:线程是轻量级进程,协程是轻量级线程;

听者知道说者为什么这样说,这叫主动,否则为被动,只有主动才能掌控节奏 ,源码会告诉我们一切。

当我们描述一个事物时,信息自然是越多越好的,但主体信息 总无非:共性、个性、起源

共性用于基本描述生成概念性认识、个性用于共性中的个体标注,是信息的进一步详细,才有了管理。

对 进程描述而言程序中描述它就是一个 task_struct,描述一个进程所需的各种资源(虚拟内存地址空间、cpu 寄存器、各种相关资源等), pid 为其身份证号,

linux 线程 (轻量级进程LWP)依然使用进程(task_struct)的方式来描述,然而又要满足虚拟地址空间共享等,在task_strcut 的成员变量中, (同一个线程组的进程)mm_struct 、file_struct 等指针,指向同一块区域,否则指向各自自己的区域(父子进程的mm 待后续分析)由于PID 是进程管理的身份证号,因此每一个task_struct 的pid 不一样。

thread_info       描述进程的基本信息
mm_struct         描述内存的结构体指针,
file_struct       描述文件描述符
signal_struct     描述信号

但是我们的用户程序中getpid()调用为什么返回一样呢,查看内核源码发现返回的是tgid,同一个线程组的tgid 值为主线程 thread_leader 的 pid.

/**
 * sys_getpid - return the thread group id of the current process
 *
 * Note, despite the name, this returns the tgid not the pid.  The tgid and
 * the pid are identical unless CLONE_THREAD was specified on clone() in
 * which case the tgid is the same in all threads of the same group.
 *
 * This is SMP safe as current->tgid does not change.
 */
SYSCALL_DEFINE0(getpid)
{
	return task_tgid_vnr(current);
}

起源

不管是系统调用 fork、vfork、kernel_thread、clone (pthread_create ), 均调用的是do_fork. 可见linux 中连线程的诞生都是使用进程创建的接口。

内核线程

pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
	return _do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
		(unsigned long)arg, NULL, NULL, 0);
}

内核线程使用的是主存而非虚拟地址空间(mm 指针为空,相应地active_mm),且不被trace(内核线程一般完成较为重要的功能,比如维护网络连接ksoftirq、脏内存回写等,如果被trace 极易发生系统级故障)。

flags 来控制新进程与旧进程的关系,是否共享vm 文件等等。

用户线程

pthread_create 本质上也是调用do_fork 创建的进程,由do_fork创建的进程都会 加入kernel 维护的 进程链表参与 kernel 调度。只不过与内核线程相比,多了虚拟地址空间访问,运行于用户态,使用系统调用陷入内核态交互处理,开销相对较内核线程大。

以上线程统可以用进程来称呼,均是linux 内核负责管理进程的生命周期

协程

以上由pthread 库用户创建的线程,本质上还是由内核参与调度处理,切换开销较大(调度要在用户态和内核态的切换),且由于线程当作进程处理,维护了很多描述信息,还要考虑抢占等复杂的内核机制。针对以上问题,更轻量级线程,协程诞生:协程完全是用户态维护的线程(不考虑系统调用),调度也由用户态自己控制,协程切换等也都由用户程序自己维护,对内核而言是看不见协程的

 g g g      g g g

lwp lwp    lwp  lwp

 CPU         cpu
内核调度lwp,lwp 调度G

golang 的协程实现原理见:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值