进程与线程比较
具体参考
小林coding
线程的上下文切换
当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的栈、寄存器等不共享的数据。
当两个线程不属于同一个进程,就进行进程的上下文切换
知识点
用户线程的整个线程管理和调度,操作系统是不直接参与的,而是由用户级线程库函数来完成线程的管理,包括线程的创建、终止、同步和调度等。
Linux 下的线程是轻量级进程,没有真正意义上的线程结构,没有为线程专门设计内核数据结构,而是通过 PCB 来模拟实现出线程的。
Linux 并不能直接给我们提供线程相关的接口,只能提供轻量级进程的接口!在用户层实现了一套多进程方案,以库的方式提供给用户进行使用,这个库就是pthread线程库(原生线程库)。
调度算法
线程库的函数
线程创建
pthread_ create函数会产生一个线程ID,存放在第一个参数指向的地址中。该线程ID和前面说的线程ID不是一回事。
前面讲的线程ID属于进程调度的范畴。因为线程是轻量级进程,是操作系统调度器的最小单位,所以需要一个数值来唯一表示该线程。
pthread_ create函数第一个参数指向一个虚拟内存单元,该内存单元的地址即为新创建线程的线程ID,属于NPTL线程库的范畴。线程库的后续操作,就是根据该线程ID来操作线程的。
可以看到线程独有的栈和其属性集合是在原生线程库中的。
线程终止
如果需要只终止某个线程而不终止整个进程,可以有三种方法:
1.从线程函数 return。这种方法对主线程不适用,从main 函数 return 相当于调用 exit。
2.线程可以调用 pthread_ exit 终止自己。
3.一个线程可以调用 pthread_ cancel 终止同一进程中的另一个线程。
注:在多线程场景下,不要使用 exit 函数,exit 函数是终止整个进程的
pthread_exit()
这里的retval一般是(void*)20,当作“返回值”,由pthread_join()接收
线程等待和线程分离
pthread_join()和pthread_detach()
1.linux线程pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。
2.unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为joinable,然后适时调用pthread_join.
3.其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦