一、什么是线程?
- LWP:light weight process 轻量级的进程,本质仍是进程(在Linux环境下)
- 进程:独立地址空间,拥有PCB
- 线程:也有PCB,但没有独立的地址空间(共享)
- 区别:在于是否共享地址空间
- Linux下: 线程:最小的执行单位 ,进程:最小分配资源单位,可看成是只有一个线程的进程。
二、Linux内核线程实现原理
类Unix系统中,早期是没有“线程”概念的,80年代才引入,借助进程机制实现出了线程的概念。因此在这类系统中,进程和线程关系密切。
- 轻量级进程(light-weight process),也有PCB,创建线程使用的底层函数和进程一样,都是clone
- 从内核里看进程和线程是一样的,都有各自不同的PCB,但是PCB中指向内存资源的三级页表是相同的
- 进程可以蜕变成线程
- 在linux下,线程最是小的执行单位;进程是最小的分配资源单位
- 线程可看做寄存器和栈的集合
代码如下(示例):
线程共享资源
- 文件描述符表
- 每种信号的处理方式
- 当前工作目录
- 用户ID和组ID
- 内存地址空间 (.text/.data/.bss/heap/共享库)
线程非共享资源
- 线程id
- 处理器现场和栈指针(内核栈)
- 独立的栈空间(用户空间栈)
- errno变量
- 信号屏蔽字
- 调度优先级
线程优缺点
优点:
- 提高程序的并发性
- 开销小
- 数据通信、共享数据方便
缺点:
- 库函数不稳定
- gdb无法调试
- 对信号支持不好
线程控制原语
#include <cstdio>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void* thrd_func(void* arg)
{
printf("thread id = %lu , pid = %u \n",pthread_self(),getpid());
return NULL;
}
int main()
{
pthread_t tid;
int ret;
printf("In main id = %lu , pid = %u \n", pthread_self(), getpid());
ret=pthread_create(&tid,NULL, thrd_func,NULL);
if (ret != 0)
{
fprintf(stderr,"pthread_create error :%s\n",strerror(ret));
printf("pthread_create error:\n");
exit(1);
}
sleep(1);
printf("In main2 id = %lu , pid = %u \n", pthread_self(), getpid());
return 0;
}