线程
概念:线程是进程内部的一条执行序列(执行流),一个进程可以包含多个线程。将main函数执行的线程称之为主线程,其他线程的线程称之为函数函数线程。
C语言如何组织一组指令—>函数
main函数:进程执行的入口。
创建线程时,需要指定线程的执行序列(函数)。
函数调用和线程函数
函数调用
1 | int main() //串行执行 |
线程函数
1 | void *fun(void *arg); |
线程的实现方式
- 用户级线程:n:1
- 内核级线程:线程的实现是在内核态 n:n
- 混合级线程: n:m
内核态线程
优点:用户程序比较简单,一个线程阻塞,可以很从容的切换到另一个线程。
缺点:切换效率低,每次切换都需要陷入内核态,占用内核稀缺的内存资源。
用户级线程
优点:灵活,内核不需要知道线程的存在,切换效率高,因为不需要陷入内核,不用修改操作系统,实现简单。
缺点:如果一个线程阻塞,则会造成整个线程的阻塞,用户程序就会相对复杂一些。
Linux系统的线程实现:
Linux实现线程的机制非常独特,从内核角度来说,他并没有线程这个概念。线程仅仅被视为一个与其他进程共享某些资源的进程。
进程和线程的区别
- 进程是资源分配的最小单位,线程是CPU调度的最小单位
- 进程有自己的独立地址空间,线程共享进程中的地址空间
- 进程的创建消耗资源大,线程的创建相对较小
- 进程的切换开销大,线程的切换开销小
Linux系统上线程库的使用
1 | int pthread_create(pthread_t *id,pthread_attr_t *attr,void *(*pthread_fun)(void *),void *arg); |
使用这个方法来测试一下
1 |
|
编译的时候要连接pthread库
给线程函数传递参数
1 | void * 传递一个小于等于4字节的值类型,传递一个地址 |
1 |
|
1 | 传递一个地址//函数线程和传递参数的线程共享传递的变量 |
1 |
|
线程之间除了地址空间共享,还有那些是共享的:
进程:.text .data .heap .stack 内核(文件描述符)
结论:同一个进程中的线程共享.data .heap .text 文件描述符(无论什么时候打开)