Bootstrap

Linux 多线程详解 —— 什么是线程

什么是线程?

linux内核中是没有线程这个概念的,而是轻量级进程的概念:LWP。一般我们所说的线程概念是C库当中的概念。

线程是怎样描述的?

线程实际上也是一个,工作线程拷贝主线程的,然后共用主线程的。线程ID是在用中pid描述的,而中tgid是线程组ID,表示线程属于该线程组,对于主线程而言,其pid和tgid是相同的,我们一般看到的进程ID就是tgid。

即:

获取线程ID和主线程ID的值

但是获取该gettid系统调用接口并没有被封装起来,如果确实需要获取线程ID,可使用:

#include
int TID =syscall(SYS_gettid);

则对线程组而言,所有的tgid一定是一样的,所有的pid一定是不一样的。主线程pid和tgid一样,工作线程pid和tgid一定不一样。

如何查看一个线程的ID

上述polkitd进程是多线程的,进程ID为731,进程内有6个线程,线程ID为731,764,765,768,781,791。

如图:

多线程如何避免调用栈混乱的问题?

工作线程和主线程共用一个,如果都向栈中压栈,必然会导致调用栈出错。

实际上工作线程压栈是压了共享区,该共享区包含了许多线程独有的资源。如图:

每一个线程,默认在共享区中占有的空间为8M,可以使用修改。

进程是资源分配的基本单位,线程是调度的基本单位。

线程独有资源

线程共享资源和环境

为什么要有多线程?

举个生活中的例子, 这就好比去银行办理业务。 到达银行后, 首先取一个号码, 然后坐下来安心等待。 这时候你一定希望, 办理业务的窗口越多越好。 如果把整个营业大厅当成一个进程的话, 那么每一个窗口就是一个工作线程。

线程带来的优势

线程带来的缺点

注意

并不是只有主线程才能创建线程, 被创建出来的线程同样可以创建线程。

不存在类似于fork函数那样的父子关系, 大家都归属于同一个线程组, 进程ID都相等, group_leader都指向主线程, 而且各有各的线程ID。

通过group_leader指针, 每个线程都能找到主线程。 主线程存在一个链表头,后面创建的每一个线程都会链入到该双向链表中。

并非只有主线程才能调用pthread_join连接其他线程, 同一线程组内的任意线程都可以对某线程执行pthread_join函数。

并非只有主线程才能调用pthread_detach函数, 其实任意线程都可以对同一线程组内的线程执行分离操作。

线程的对等关系:

整理了一些个人觉得比较好的学习书籍、大厂面试题、技术教学视频资料共享在里面(包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等.),有需要的可以自行添加哦!~

以上有不足的地方欢迎指出讨论。