1.线程的三种退出方式
1.1 普通线程的退出对于主控线程来说不受影响
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <string.h>
void* ThreadJob1(void* arg)
{
printf("thread1 tid:0x%x thread running...\n", (unsigned int)pthread_self());
return (void*)8;
}
void* ThreadJob2(void* arg)
{
printf("thread2 tid:0x%x thread running...\n", (unsigned int)pthread_self());
pthread_exit((void*)6);
}
void* ThreadJob3(void* arg)
{
while(1)
{
printf("thread3 tid:0x%x thread running...\n", (unsigned int)pthread_self());
sleep(1);
}
}
int main()
{
pthread_t tid[3];
void* re_val;
pthread_create(&tid[0], NULL, ThreadJob1, NULL);
pthread_join(tid[0], &re_val);
printf("main thread join thread1 return number:%d\n", (int)re_val);
pthread_create(&tid[1], NULL, ThreadJob2, NULL);
pthread_join(tid[1], &re_val);
printf("main thread join thread2 exit code:%d\n", (int)re_val);
pthread_create(&tid[2], NULL, ThreadJob3, NULL);
sleep(2);
pthread_cancel(tid[2]);
pthread_join(tid[2], &re_val);
printf("main thread join thread3:%d\n", (int)re_val);
return 0;
}
- 1.若将 ThreadJob3 函数中的while循环中的循环体删除,只留下 while(1); 这一句,那么线程就无法退出,因为没有发生系统调用,cancel函数需要有系统调用才会进行;
1.2 信号的处理条件:中断、异常、系统调用
1.3 cancel 结束事件:系统调用;对于cancel最好是使用空的系统调用
1.4 pthread_testcancel 函数会产生空的系统调用,一般常与 pthread_cancel 函数同时使用
1.5 pthread_detach 函数
- 1.线程分离函数
- 2.参数:线程的tid
- 3.函数的作用是将线程设置为分离态;线程结束系统进行结束,不用 pthread_join 函数回收,无法返回退出码
- 4.对设置为分离态的线程进行回收就会出错
1.6 分离态与回收态是互斥的
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <string.h>
void* ThreadJob(void* arg)
{
pthread_detach(pthread_self());
while(1)
sleep(1);
}
int main()
{
void* re_val;
int err;
pthread_t tid;
pthread_create(tid, NULL, ThreadJob, NULL);
sleep(1);
if((err=pthread_join(tid, &re_val)) > 0)
printf("ERROR:join[%s]\n", strerror(err));
printf("Main thread join thread:%d\n", (int)re_val);
return 0;
}
1.7 线程的大小就是线程栈的大小,默认为8M
1.8 一个线程所能创建的最大线程个数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <string.h>
void* ThreadJob(void* arg)
{
while(1)
sleep(1);
}
int main()
{
void* re_val;
int err;
int flag = 0;
pthread_t tid;
while(1)
{
if((err=pthread_create(tid, NULL, ThreadJob, NULL)) > 0)
{
printf("ERROR:[%s]\n", strerror(err));
exit(0);
}
printf("线程个数 = %d\n", ++flag);
}
return 0;
}
- 1.在32位Linux系统下,该程序的结果是300+;
- 2.在64位Linux系统下,该程序的结果是10000+;因为其内存是0~4T,因此可以创建很多线程,但是因为Linux系统有限制,因此会在10000左右停止;
1.9 更改线程属性
- 1.更改线程属性需要一个结构体: pthread_attr_t ;
- 2.初始化线程属性结构体的函数: pthread_attr_init ;
- 3.销毁线程属性结构体的函数: pthread_attr_destroy ;
- 4.更改分离态还是可回收态函数: pthread_attr_setdetachstate ;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <string.h>
void* ThreadJob(void* arg)
{
while(1)
sleep(1);
}
int main()
{
pthread_t tid;
int detach_state;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_getdetachstate(&attr, &detach_state);
if(detach_state == PTHREAD_CREATE_JOINABLE)
printf("DFL JOINABLE\n");
else
printf("DFL DETACHED\n");
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_getdetachstate(&attr, &detach_state);
if(detach_state == PTHREAD_CREATE_JOINABLE)
printf("SET JOINABLE\n");
else
printf("SET DETACHED\n");
pthread_create(&tid, &attr, ThreadJob, NULL);
int err;
if((err=pthread_join(tid, NULL)) > 0)
printf("ERROR:[%s]\n", strerror(err));
pthread_attr_destroy(&attr);
return 0;
}
1.10 获取线程栈的大小
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <string.h>
void* ThreadJob(void* arg)
{
while(1)
sleep(1);
}
int main()
{
int detach_state;
size_t stack_size;
void* stack_addr;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_getstack(&attr, &stack_addr, &stack_size);
printf("DFL STACK ADDR:%p SIZE:%d\n", stack_addr, stack_size);
pthread_attr_destroy(&attr);
return 0;
}
1.11 更改线程栈的大小
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <string.h>
void* ThreadJob(void* arg)
{
while(1)
sleep(1);
}
int main()
{
pthread_t tid;
void* stack_addr;
size_t stack_size;
int detach_state;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_getstack(&attr, &stack_addr, &stack_size);
printf("DFL STACK ADDR:%p SIZE:%d\n", stack_addr, stack_size);
stack_addr = (void*)malloc(0x100000);
pthread_attr_setstack(&attr, stack_addr, 0x100000);
pthread_attr_getstack(&attr, &stack_addr, &stack_size);
printf("AFTER STACK ADDR:%p SIZE:%d\n", stack_addr, stack_size);
pthread_attr_destroy(&attr);
return 0;
}