进程:是系统分配资源的最小单位(分配虚拟内存)
线程:是系统调度的最小单位(分配时间片)
//创建线程
int pthread_create(pthread_t *thread, //线程的tid 是唯一的
const pthread_attr_t *attr, //线程的属性
void *(*start_routine) (void *), //任务函数
void *arg);//传递给任务函数的参数
//编译的时候记得添加 -lpthread
//线程等待函数
#include <pthread.h>
//等待子线程结束并回收子线程的资源(虚拟栈)
int pthread_join(pthread_t thread, void **retval);
//参数一:需要等待的线程TID
//参数二:线程的退出值 (保存指针的地址)
//线程退出函数:
#include <pthread.h>
void pthread_exit(void *retval);
//参数一:线程的退出值 (保存数据的地址)
//设置线程的属性
//设置线程的栈大小
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
//参数一:属性
设置栈的大小时记得大于: (16384) bytes.
//获取线程的栈大小
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
返回值:设置成功 0
失败 非0
设置线程为分离属性:让他自己回收自己的资源
int pthread_detach(pthread_t thread);
使用线程注意事项:
1.主线程结束,所有的子线程都会死亡。
2.全局变量与线程中的局部变量同名则优先使用局部变量。
3.所有的线程共享全局变量,线程之间的通信只需要使用全局变量即可!!
4.当一个线程被设置为分离属性后,他就自己回收资源,pthread_join等待失效。
----------------线程的取消-----------------------------
int pthread_cancel(pthread_t thread);
参数一:需要取消的线程的TID号
屏蔽线程的取消信号:不会把请求给扔掉,他会保留起来,当我们重新开启取消请求的时候,就立即响应
#include <pthread.h>
//是否启动线程取消请求
int pthread_setcancelstate(int state, int *oldstate);
参数一:取消的状态开关
PTHREAD_CANCEL_ENABLE 开启取消请求
PTHREAD_CANCEL_DISABLE 关闭取消请求
参数二:原来的取消状态 NULL 即可
//设置响应状态
int pthread_setcanceltype(int type, int *oldtype);
//参数一:响应状态的模式
PTHREAD_CANCEL_DEFERRED 延时响应
PTHREAD_CANCEL_ASYNCHRONOUS 立即响应
参数二:原来的响应状态 NULL即可
成功:返回 0
失败:返回 非0
//注册线程的取消处理函数 (他是一个宏函数来的)
void pthread_cleanup_push(void (*routine)(void *),void *arg);
参数一:需要注册的取消处理函数
参数二:传递给取消处理函数的参数
void pthread_cleanup_pop(int execute);
参数一:是否启动取消处理函数
0 不执行取消处理函数
非0 执行取消处理函数
//取消处理的注册必须要与是否启动配套使用,pthread_cleanup_push必须在 pthread_cleanup_pop之前
//调用pthread_cleanup_pop就会执行定义好的处理函数
//线程中的互斥锁:保护各个线程中的共享资源,例如:全局变量,堆空间。。。。。
//初始化线程锁
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
//参数一:需要初始化的线程锁
//参数二:线程锁的属性 默认为:NULL
//上锁操作 假如锁住了就没有办法继续上锁会阻塞
int pthread_mutex_lock(pthread_mutex_t *mutex);
//尝试上锁 不会阻塞的
int pthread_mutex_trylock(pthread_mutex_t *mutex);
//解锁 可以一直解锁不会阻塞
int pthread_mutex_unlock(pthread_mutex_t *mutex);
//销毁锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
//注意:定义锁的时候,一般要把锁定义为全局变量,在所有线程中有效!!
条件变量的作用:使各个线程之间协调工作。条件变量的使用必须要配合上互斥锁
1、初始化条件变量
int pthread_cond_init(pthread_cond_t*cond, pthread_condattr_t *cond_attr);
参数一:需要初始化的条件变量
参数二:条件变量的属性
2.等待条件变量的来临
//无限等待
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
//参数一:等待的条件
//参数二:阻塞他的锁 (先上锁,再进入等待条件,当进入等待条件时,系统会自动帮我们解锁,!!当条件触发时再次上锁!)
//当时间超过设置的时间后他就不会再等待
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t*mutex, const struct timespec *abstime);
3.发送条件变量
//唤醒一个条件变量
int pthread_cond_signal(pthread_cond_t *cond);
//唤醒所有条件变量
int pthread_cond_broadcast(pthread_cond_t *cond);
4.销毁的条件变量
int pthread_cond_destroy(pthread_cond_t *cond);
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
//全局变量
int poin=0;
int ext=168;
void *func(void *arg)
{
while(1)
{
printf("func_poin=%d\n",poin++);
sleep(1);
if(poin == 3)
{
//线程退出
printf("exit=%p\n",&ext);
pthread_exit((void *)&ext);
}
}
}
int main()
{
int a=100;
printf("main_poin=%d\n",poin);
//创建一个任务线程
pthread_t tid=0;
pthread_create(&tid,NULL,func,(void *)&a);
//传递一个参数给 任务线程,让任务线程从传递的参数开始打印
printf("main_poin=%d\n",poin++);
printf("等待子线程结束\n");
//保存指针的地址
void *retval=NULL;
pthread_join(tid,&retval);//等待子线程结束并回收子线程的资源(虚拟栈)
printf("retval=%p\n",retval);
printf("retval=%d\n",*((int *)retval));
printf("等待子线程结束完毕!!\n");
}
运行效果如下:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
//全局变量
int poin = 100;
//取消处理函数
void del(void *arg)
{
printf("已经把线程处理完毕啦!!\n");
}
//子线程
void *func(void *arg)
{
//关闭取消请求
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
pthread_cleanup_push(del,NULL); //注册线程取消处理函数
while(1)
{
printf("func_poin=%d\n",poin++);
if(poin == 110)
{
//重新开启取消请求
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
}
sleep(1);
}
pthread_cleanup_pop(0);//取消线程处理函数
pthread_exit(0);
}
int main()
{
//创建一个任务线程
pthread_t tid=0;
pthread_create(&tid,NULL,func,NULL);
printf("等待子线程结束\n");
while(1)
{
int a=0;
scanf("%d",&a);
if(a== 110)
{
//线程取消信号
pthread_cancel(tid);
break;
}
}
printf("clean up\n");
pthread_join(tid,NULL); //回收线程的资源
printf("等待子线程结束完毕!!\n");
sleep(1);
}
运行效果如下图:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *func(void *arg)
{
printf("runing\n");
}
int main()
{
//创建一个线程
pthread_t tid=0;
pthread_attr_t attr;
bzero(&attr,sizeof(attr));
int ret = pthread_attr_init(&attr); /*初始化线程属性*/
if (ret != 0)
return -1;
//设置栈空间的大小
ret = pthread_attr_setstacksize(&attr, 65536);
if(ret != 0)
{
perror("set fail\n");
exit(0);
}
//设置完毕后创建!!
pthread_create(&tid,&attr,func,NULL);
size_t size;
//获取栈的大小
pthread_attr_getstacksize(&attr,&size);
printf("size=%lu\n",size);
pthread_join(tid,NULL);
}
运行效果如下图:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
//全局变量
int poin = 100; //共享资源
pthread_mutex_t mutex; //定义为全局变量,在所有线程中有效
//子线程
void *func(void *arg)
{
while(1)
{
//执行上锁操作
pthread_mutex_lock(&mutex);
//处理共享资源
printf("func_poin=%d\n",poin);
pthread_mutex_unlock(&mutex);
}
}
int main()
{
//初始化线程锁
pthread_mutex_init(&mutex,NULL);
//创建一个任务线程
pthread_t tid=0;
pthread_create(&tid,NULL,func,NULL);
//设置为分离属性 自己回收资源
pthread_detach(tid);
while(1)
{
//执行上锁操作
pthread_mutex_lock(&mutex);
//修改共享资源
printf("main_poin=%d\n",poin++);
pthread_mutex_unlock(&mutex);
}
}