----------------线程----------------------
进程:系统分配资源的最小单位,划分虚拟内存空间的过程;
线程:系统调度的最小单位,系统分配时间片的过程,进程的时间片会被线程划分
--------------线程创建--------------
#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
参数:thread--线程的id号,唯一的
参数:attr----线程的属性
参数:start_routine --函数指针,void* 类型的返回值,void* 类型参数的函数
参数:arg-----线程函数输入的参数的地址
注意:
1.进程死亡(return exit() 被信号杀死),该进程中的所有线程都会死亡;最后一条线程调用pthread_exit()
2.全局变量与局部变量同名,优先使用局部变量;
3.所有线程共享进程里面的资源,除了自己的栈空间,线程的栈空间与进程的相互独立,但线程的栈空间还在进程的栈空间里;
4.进程和线程中的变量可以通过地址访问,因为二者的栈空间在同一块区域;
---------------线程退出--------------
#include
void pthread_exit(void *retval);
参数:
pthread_exit(NULL);
说明:
1.主函数调用 pthread_exit 只会退出主线程对子线程没有影响;
2.主函数调用 return ,退出进程,所有的子线程都会死亡;
3.子线程调用 return ,结束当前线程,对其他线程没有影响;
---------------线程的资源回收---------
#include
int pthread_join(pthread_t thread, void **retval);
参数:pthread--需要回收的线程 tid
参数:retval---线程的退出参数
pthred_join(tid,NULL);
#include<stdio.h>
#include<pthread.h>
int a =0,b = 0;
void *func1(void* arg)
{
static int func1_param = 100;
while(a<5)
{
printf("a = %d\n",a++);
sleep(1);
}
printf("func1 exit param %d\n",func1_param);
pthread_exit((void*)&func1_param);//线程退出的参数
}
void *func2(void* arg)
{
while(1)
{
printf("b = %d\n",b++);
sleep(1);
}
}
int main()
{
int a =0,b = 0;
//创建线程id
pthread_t tid1,tid2;
//创建线程
pthread_create(&tid1,NULL ,func1 ,NULL);
pthread_create(&tid2,NULL ,func2 ,NULL);
void* param = NULL;
pthread_join(tid1,¶m);//得到func1退出时带回的参数,主意类型
printf("get func1 exit param %d\n",*(int*)param);
while(1);
return 0;
}
输出:
xc@xc-Lenovo-G480:~/IO/4-pthread$ gcc testpthread.c -o testpthread -lpthread
xc@xc-Lenovo-G480:~/IO/4-pthread$ ./testpthread
a = 0
b = 0
a = 1
b = 1
a = 2
b = 2
a = 3
b = 3
a = 4
b = 4
func1 exit param 100
b = 5
get func1 exit param 100
b = 6
---------------线程属性的设置----------------
1.初始化线程属性 pthread_attr_init()
2.设置线程属性 pthread_attr_set()
3.使用线程属性去创建线程
4.销毁线程属性 pthread_attr_destroy()
#include <pthread.h>
int pthread_attr_init(pthread_attr_t *attr);
参数:attr--需要初始化的线程属性
int pthread_attr_destroy(pthread_attr_t *attr);
参数:attr--需要销毁的线程属性
设置线程的属性:
#include <pthread.h>
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
参数:attr--需要初始化的线程属性
参数:detachstate--属性的类型
PTHREAD_CREATE_DETACHED (分离属性)
PTHREAD_CREATE_JOINABLE (接合属性)
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
还可以使用如下两个其中一个放在主函数结尾部分,不要在创建线程属性:
int pthread_join(pthread_t thread, void **retval);//接合属性线程
int pthread_detach(pthread_t thread);//分离属性线程
pthread_join(tid1,¶m);
pthread_detach(tid1);
//设置线程的分离属性
pthread_attr_t attr;
pthread_attr_init(&attr);
//设置线程属性为分离属性
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
//创建线程id
pthread_t tid1,tid2;
//创建线程
pthread_create(&tid1,NULL ,func1 ,NULL);
pthread_create(&tid2,&attr ,func2 ,NULL);
------获取栈空间------
#include <pthread.h>
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
第二个参数为输出参数
//
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
设置栈大小的时候注意:The stack size is less than PTHREAD_STACK_MIN (16384) bytes.
size_t size = 0;
pthread_attr_getstacksize(&attr3,&size);
printf("get stack size %ld\n",size); // size_t --- long int
//
get stack size 8388608
-----------------线程的取消---------------------
#include <pthread.h>
int pthread_cancel(pthread_t thread);
参数:创建线程是的线程id
pthread_cancel(tid);
----------------关闭线程取消功能-----------------
#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
---------
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);//
注意:
1.放在那个线程,取消那个线程的关闭线程功能
2.屏蔽取消请求並不是把请求给丢弃,只是暂时不响应,当恢复取消请求后就立即响应
-------------注册线程取消函数--------------
#include <pthread.h>
void pthread_cleanup_push(void (*routine)(void *),void *arg);
void pthread_cleanup_pop(int execute);
说明:
pthread_cleanup_push : 把处理函数,压栈
pthread_cleanup_pop : 把处理函数,出栈
注意:
处理函数(线程)正在执行时,
当线程被杀死时,不管出栈函数参数是0,还是非0, 都会去执行处理函数
当线程正常退出时,出栈函数的参数是0,则不执行处理函数;非0,则执行处理函数