1、线程部分
1)POSIX线程(参考man pthreads)
使用g++ -v,可以获知系统使用POSIX线程模型(见输出中”Thread model: posix“这一行)。
LinuxThreads和NPTL是POSIX线程在Linux上的两种不同实现。它们都是所谓的1:1实现,即每个线程映射到内核的一个调度实体。它们都使用Linux的clone()系统调用。
我们可以通过getconf -a获知系统使用的glibc版本和线程实现:
(1)LinuxThreads:最初的Pthreads实现。glibc从2.4开始不再支持LinuxThreads。主要特征:
I、进程中除了主线程和pthread_create创建的线程外,还会创建一个管理线程。管理线程负责线程的创建和终止。
II、线程间不共享进程ID(LinuxThreads线程实际上被实现为进程,但彼此之间共享很多信息)。使用ps可以观察到它们是一个个独立进程。
(2)NPTL(Native POSIX Threads Library):Pthreads的新实现。与LinuxThreads相比,NPTL提供了与POSIX.1更好的一致性,以及在创建大量线程时更佳的性能表现。glibc从2.3.2开始支持NPTL。主要特征:
I、NPTL不使用管理线程。
II、一个进程中的所有线程属于相同的线程组,并共享一个PID(也是所谓的线程组ID,TGID)。
不同线程使用TID(参考以下的gettid()及ps -eLf)区分。线程组的leader就是TID与PID相同的那个线程。
Linux特有的gettid()系统调用可以获得线程ID,即TID(注意类型是pid_t)。TID与POSIX线程ID(pthread_t)是不同的。
如图,一个进程pthread_create创建五个线程之后,我们使用ps -eLf获取线程信息:
这里LWP(Light Weight Process,轻量级进程)字段对应上面所说的TID。
III、NPTL使用Linux特有的futex()系统调用实现线程的同步原语(互斥锁,线程joining等)。
2)其他一些与线程相关的函数
(1)clone()系统调用
与fork()不同的是,clone()允许子进/线程共享调用进程的诸如内存空间、文件描述符表等资源。
clone()可用于创建线程。调用时如果设置CLONE_THREAD,则子线程与调用者在相同的线程组,共享同一个PID;否则创建一个新进程,而调用进程作为其父进程。
(2)tgkill():Linux特有的系统调用
tgkill()发送信号到一个特定线程,而kill发送信号到整个进程(线程组)。
不断学习中。。。