linux 线程和条件变量

进程:是系统分配资源的最小单位(分配虚拟内存)
线程:是系统调度的最小单位(分配时间片) 

//创建线程
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);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值