1. 10.3 线程
与进程类似,线程是允许应用程序并发执行多个任务的一种机制。一个进程可以包含多个线程。同一个程序中的所有线程均会独立执行相同程序,且共享同一份全局内存区域。
同一进程中的多个线程可以并发执行。在多处理器环境下,多个线程可以同时并行。如果一个线程因等待 I/O 操作而遭阻塞,那么其他线程依然可以继续运行。
在 Linux 中,通过系统调用 clone()
来实现线程的。从前面的介绍,我们知道,该系统调用也可以用来创建进程。实际上,从内核的角度来说,它并没有线程这个概念。Linux 把所有的线程都当作进程来实现。内核并没有准备特别的调度算法或是定义特别的数据结构来表征线程。相反,线程仅仅被视为一个使用某些共享资源的进程。所以,在内核中,它看起来就是一个普通的进程(只是该进程和其他一些进程共享某些资源,如地址空间)。
在 Go 中,通过 clone()
系统调用来创建线程,其中的 clone_flags
为:
cloneFlags = _CLONE_VM | /* share memory */
_CLONE_FS | /* share cwd, etc */
_CLONE_FILES | /* share fd table */
_CLONE_SIGHAND | /* share sig handler table */
_CLONE_THREAD /* revisit - okay for now */
也就是说,父子俩共享了地址空间 (_CLONE_VM)、文件系统资源 (_CLONE_FS)、文件描述符 (_CLONE_FILES) 和信号处理程序 (_CLONE_SIGHAND)。而 _CLONE_THREAD
则会将父子进程放入相同的线程组。这样一来,新建的进程和父进程都叫做线程。