当前位置:

深入浅出线程原理

访客 2024-01-12 1373 0

Linux 中的线程本质

线程接口由 Native POSIX Thread Library 提供,即:NPTL 库函数

线程被称为轻量级进程 (Light Weight Process)

每一个线程在内核中都对应一个调度实体,拥有独立的结构体 (task_struct)

  • 内核设计:一个进程对应内核中的一个结构体,对应一个进程标识
  • 引入线程:线程是内核的调度实体,在内核中必然对应一个结构体

用户模式:一个进程中存在多个线程

内核模式:每个线程是一个独立的调度实体

另一个视角

拥有多线程的进程,又被称为线程组 (谁是线程组长?)

在内核数据结构 task_struct 中存在 pid 和 tgid:

pid_t pid => 线程标识符 (Thread ID)

pid_t tgid => 线程组标识符 (Thread Group ID)

进程创建后默认拥有一个线程,即:主线程 (默认执行流)

主线程的 LWP 标识与进程标识符相同,即:主线程为线程组长

其他子线程创建后隶属于当前进程:

  • 子线程的 LWP 标识符各不相同,且与进程标识符相同
  • 子线程调用 getpid() 的结果相同 (why?)

下面的程序输出什么?为什么?

问题

对于线程来说,pthread_t 类型的标识符 与 pid_t 类型标识有什么不同?

使用 ps 命令查看线程信息

-e => Select all processes

-L => Show threads,possibly with LWP and NLWP columns

-f => Do full-format listing

ps -eLf => to get info about threads

实验程序

多线程内核模型

Linux 内核中的基本调度单位为 task_struct,即:内核中以 "任务" 作为调度的基本单位

值得思考的问题

多线程之间是否有 "父子关系" ?

答:无!

进程中只有主线程和子线程,线程之间没有 "父子关系"

主线程如果先于子线程结束会发生什么?

Linux 中主线程如果执行结束,则进程结束

进程结束则进程资源被释放,子线程被迫结束

使用 kill 命令是否能够 "杀死" 指定线程 ?

kill 命令默认发送信号 SIGTERM,而信号的目标是进程

因此,kill 任意子线程的 pid_t 将导致整个进程结束

pthread_t 究竟是什么数据类型 ?

pthread_t 是 POSIX Thread 中的接口,具体定义与系统相关

通常情况下,pthread_t 的具体定义是 一个整型值

  • Linux 中 pthread_t 的具体定义是 64 位整数 (保存地址值)
  • 其他系统中 pthread_t 直接映射为 Task ID 值
  • 对于一些特殊的系统,pthread_t 是一个结构体

Linux 多线程 API 函数

线程标识相等判断

int pthread_equal(pthread_t t1, pthread_t t2);

如果 t1 和 t2 相等,返回非 0 值,否则返回 0 值

注意:

Linux 系统编程时,可直接用 t1 == t2 的方式判断是否相等

编写可移植的多线程代码,使用 pthread_equal() 判断是否相等

发表评论

  • 评论列表
还没有人评论,快来抢沙发吧~