头文件 #include <pthread.h>
1.0 pthread_t
用于声明线程ID;
pthread_t thread;
1.1
1. Linux线程创建函数: pthread_create();
//注意,线程创建之后会立即执行线程所指向的那个函数;
函数原型:int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
参数介绍:
第一个参数是 指向线程标识符的指针,也就是线程对象的指针;
第二个参数是 用来设置线程属性;
第三个参数是 线程运行函数的地址;
//注释: 一般这个函数执行时间比较长(大多有while循环),做的事情比较多,而且线程创建之后
会马上执行,所以需要,把线程加入 pthread_join() 等待线程执行完,并让其释放系统资源;
意思也就是,创建线程,执行线程里面的while循环,如果这时候把线程加入Pthread_join(),
就会等待... 如果是单次动作(执行时间比较短),也就不需要线程了;
第四个参数是 线程要运行函数的参数(参数如果有多个,往后依次添加);
返回值:0表示创建成功,-1表示创建失败;
//注意:线程默认堆栈大小是 1 MB,也就是说系统每创建一个线程,就会申请 1MB 的内存,如果线程创建失败,极有可能是内存不足导致的;
举个栗子:
pthread_t th;
void sum()
{
while(1){
printf("Good!\n");
}
}
pthread_create(&th, NULL, sum, NULL)
th在这里就代表线程ID,到后面直接调用线程ID,就开始工作线程内的东西;
2.什么是线程的分离状态、非分离状态
线程的分离状态 决定 线程以什么方式结束自己;
创建的线程属性默认的是 非分离状态,在这种情况下,原有的线程等待创建的线程(因为创建线程之后就会执行线程函数代码)结束,只有等到 pthread_join() 函数结束之后,创建的线程才算终止,才可以释放系统资源;
而 分离状态 它没有被其他线程所等待,线程运行结束的时候就终止了,就会自动释放占用的系统资源,
意思也就是说,使用 pthread_create() 创建一个线程,该线程的属性是 非分离状态,如果不适用 pthread_join() 函数,线程结束的时候并不会终止,也就不会释放占用的系统资源;
但是 一直调用 pthread_join() 函数的同时也会引发一些 线程阻塞 的问题,所以引出了线程分离,也就是 pthread_detach() 函数;
2.1 线程阻塞问题:
一般情况下,一个程序占用一个进程,一个进程有很多线程,但是也有一个主线程;pthread_create() 创建的线程,默认情况下是 非分离状态,当线程运行结束的时候,如果不用 pthread_join() 函数回收线程,
并不会释放其占有的系统资源,就会造成内存泄漏,
但是,如果使用了 pthread_join() 函数回收线程,不可避免会有一个等待过程,主线程在等待该线程回收的时候,就会处于阻塞状态,这样就会影响主线程处理其他链接请求,
所以就需要寻找一种状态(分离状态),在线程结束的时候自动释放占用的系统资源;
//总结:程序员根据自身需要,适当设置线程的 分离状态;
3. pthrad_join() 函数介绍
函数原型:int pthread_join(pthread_t thread, void **retval);
函数功能:以阻塞的方式等待线程ID为 thread 的线程结束,
参数介绍:
第一个参数:thread 线程标识符,线程ID;
第二个参数:用户定义的指针,用于存放 被等待线程 的返回值;
返回值:0代表成功,失败返回一个错误号;
4.pthread_exit()
显式地退出一个线程,在线程完成工作以后无需继续存在的时候调用此函数;
//注释:在 main() 结束时自动终止所有线程;
默认是谁创建子线程,谁负责子线程的资源回收,当父线程退出之后,子线程也要退出。
所以,父线程退出的时候,都要确保子线程的退出;可以使用 pthread_join() 函数阻塞 等待子线程的退出信号
pthread_detach(threadid) 函数的功能就是使线程 ID 为 threadid 的线程处于分离状态(可以是非父子关系),
一旦线程处于分离状态,当父线程退出的时候,子线程的资源就会被立刻回收。
如果不处于分离状态,当父线程退出的时候,子线程仍然占用计算机系统资源,直到调用 pthread_join(threadid, NULL) 函数获取线程的退出状态。
被创建的子线程也可以自己分离自己,子线程调用 pthread_detach(pthread_self()) 就是分离自己,这是因为 pthread_self() 函数自身返回的就是自身的id;
//pthread_create会导致内存泄露!--------------想想为什么?