文章目录
1,线程概念
进程 | 线程 |
---|---|
·进程有独立的地址空间 ·Linux为每个进程创建task_struct(在内核中创建任务结构体) ·每个进程都参与内核调度,互不影响 |
·进程在切换时系统开销大(进程执行的时候有时间片,时间片用完了,或进入等待态了,内核就需要去调度,系统要刷新cache和tlb(页表)) ·很多操作系统引入了轻量级进程LWP(即线程) ·同一进程中的线程共享相同地址空间 ·Linux不区分进程(独占地址空间)、线程(共享相同地址空间),(系统都认为这是一个任务,都会创建task_struct) |
2,线程特点
- 通常线程指的是共享相同地址空间的多个任务
- 使用多线程的好处
·大大提高了任务切换的效率
·避免了额外的TLB & cache的刷新
3,线程共享资源–私有资源
-
一个进程中的多个线程共享以下资源
·可执行的指令
·静态数据
·进程中打开的文件描述符
·当前工作目录
·用户ID
·用户组ID -
每个线程私有的资源包括
·线程ID (TID)
·PC(程序计数器)和相关寄存器
·堆栈
·错误号 (errno)
·优先级
·执行状态和属性
4,Linux线程库–pthread线程库中提供了如下基本操作
a,创建线程pthread_create()
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*routine)(void *), void *arg);
- 成功返回0,失败时返回错误码
- thread 线程对象
- attr 线程属性,NULL代表默认属性
- routine 线程执行的函数
- arg 传递给routine的参数,不需要旳时候传NULL
b,回收线程pthread_join()
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
- 成功返回0,失败时返回错误码
- thread 要回收的线程对象
- 调用线程阻塞直到thread结束
- *retval 接收线程thread的返回值
c,结束线程pthread_exit()
#include <pthread.h>
void pthread_exit(void *retval);
- 结束当前线程
- retval可被其他线程通过pthread_join获取(retval不能是当前线程栈中创建的地址(不能是局部变量的地址),因为线程一结束,线程所有资源会被释放)
- 线程私有资源被释放
5,线程示例
char message[32] = “Hello World”;//全局变量存放在静态存储区,可以被所有线程访问
void *thread_func(void *arg);
int main(void)
{
pthread_t a_thread;
void *result;
if (pthread_create(&a_thread, NULL, thread_func, NULL) != 0)
{
printf(“fail to pthread_create”); exit(-1);
}
pthread_join(&a_thread, &result);//等待a_thread线程结束,结束后接受返回值
printf(“result is %s\n”, result);
printf(“message is %s\n”, message);
return 0;
}
void thread_func(void *arg)
{
sleep(1);
strcpy(message, “marked by thread”);
pthread_exit(“thank you for waiting for me”);//等价于return “thank you for waiting for me”;
}
$ gcc -o test test.c -lpthread//链接pthread线程库
$ ./test
thank you for waiting for me
marked by thread
main函数结束,进程就会结束,进程中所有的线程都会结束