1. 介绍
1.1 线程:也称为轻量级进程,线程的上下文开销比进程小很多
1.2 使用线程的好处:
- 大大提高了任务切换的效率
- 避免了额外的TLB&cache(高速缓存)的刷新
1.3 linux里同样用task_struct 来描述一个线程,线程和进程都参与统一的调度。
1.4 一个进程中可以有多个线程,最多能创建381个线程:
共享一部分资源,也有自己的私有资源
1.5 线程的操作用的是 POSIX 标准的通用线程库,第三方库pthread.h
编译的时候需要链接上选项,加-lpthread
2. 线程的操作
线程的操作主要包括创建、阻塞等待某个线程、退出线程,下边将一一介绍。
2.1 pthread_create():--线程的创建
函数原型:
函数原型:
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
参数:
①thread,线程的标识符。
②attr,线程属性设置,NULL表示缺省属性。
③start_routine,回调函数,就是线程要执行的函数,就是线程部分
④arg,传递给 start_routine 的参数
返回值:
成功,返回0
出错,返回错误码,是个大于0的数,errno的值。
2.2 pthread_join:--阻塞等待一个线程的退出,回收其资源,pthread_join使一个线程等待另一个线程结束。
函数原型:
int pthread_join(pthread_t thread, void **retval);
参数:
①thread,要等待其退出的线程的表示符
②retval,接收退出线程的状态。
说明:当程序运行到这个函数的地方后,将会阻塞的等待,等待着
2.3 pthread_exit: --线程退出
函数原型:
void pthread_exit(void *retval);
参数:
retval,线程结束时返回的字符串,通过 pthread_join 函数来接收。
函数原型:
int pthread_join(pthread_t thread, void **retval);
参数:
①thread,要等待其退出的线程的表示符
②retval,接收退出线程的状态。
说明:当程序运行到这个函数的地方后,将会阻塞的等待,等待着
2.3 pthread_exit: --线程退出
函数原型:
void pthread_exit(void *retval);
参数:
retval,线程结束时返回的字符串,通过 pthread_join 函数来接收。
3. 例子
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *handler(void *arg);
int main(int argc, const char *argv[])
{
pthread_t thread;
void *retval;
if (pthread_create(&thread, NULL, handler, NULL) != 0)
{
perror("fail to pthread_create");
return -1;
}
pthread_join(thread, &retval); //阻塞的等待
puts("==========");
printf("%s\n", (char *)retval);
while (1)
{
sleep(1); // 睡眠的等待1s
puts("main worldhello");
}
return 0;
}
void *handler(void *arg)
{
int i = 3;
while (i > 0)
{
sleep(1);
puts("handler worldhello");
i--;
}
pthread_exit("exit ...");
}
输出结果如下:
./build/a.out
handler worldhello
handler worldhello
handler worldhello
==========
exit ...
main worldhello
main worldhello
main worldhello
main worldhello