Linux之含互斥量线程封装(接口思想)

本文介绍了一种基于接口思想创建线程对象的方法,通过将执行体和功能体分离以降低耦合度,展示了如何使用互斥量保护共享资源,并提供了一个递增全局变量的线程示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*基于接口思想创建线程对象*/
#include<iostream>
#include<unistd.h>
#include<string.h>
#include<pthread.h>
//接口只需要留下基本的框架,内容有派生去完成,也就是接口留下最基本的共性
/*===============功能体接口(不受执行体是线程还是进程,功能体的派生必须可以给这两种执行体对象利用,从而减少耦合度)=====================*/
int i=0;
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;//声明并初始化互斥量,也可用pthread_mutex_init(&mutex,NULL);来初始化。
class whatfuntion
{
public:
	whatfuntion()
	{

	}
	virtual ~whatfuntion()
	{

	}
public:
	virtual void* exactfuntion(void* w_val=NULL)
	{
		
	}
};


/*==================执行体接口(可以派生出进程对象和线程对象,而且可以利用到功能体的对象)=====================*/
class ZXtype
{
public:
	ZXtype(whatfuntion *funtion)//型参是基类指针,实参是派生类指针,从而完成多态
	{
		ZXtype_exact_funtion=funtion;//执行体要实习什么功能,从而把功能对象的指针赋予它
	}
	virtual ~ZXtype()
	{

	}
	virtual int ZXtype_run(void* val=NULL)//执行体虚函数,可以在派生中重写,让对象为线程执行体或进程执行体
	{
	
	}
	virtual int ZXtype_wait()//等待,派生中根据要派生出线程还是进程来重写为线程等待还是进程等待
	{
	
	}
	
protected:
	whatfuntion * ZXtype_exact_funtion;//功能对象的指针(ZXtype派生对象的指针作为执行体对象的构造函数的参数)
};
/*=============派生线程==========================
*/

class pthread:public ZXtype
{
public:
	pthread(whatfuntion *funtion):ZXtype(funtion)
	{
	}
	virtual ~pthread()
	{
	}
	int run(void *val=NULL)//创建线程
	{
		m_val=val;
		int err;
		err=pthread_create(&n_pthread_id,NULL,ZXtype_funtion,this);//this指针为参数,但其不是功能函数的参数,而是线程在主函数要跳转到功能函数的使命
		if(err!=0)
		{
			std::cout<<"pthread_create is fail,"<<strerror(err)<<std::endl;
			return 0;
		}
		return 0;
	}
	int wait()//主线程调用wait中的pthread_join等待线程返回,同时打印线程的返回值
	{
		void* return_val;
		int err=pthread_join(n_pthread_id,&return_val);//pthread_wait中接受返回值的参数必须是void**,但取出返回值内容为void*
		if(err!=0)
		{
			std::cout<<"pthread_join is fail,"<<strerror(err)<<std::endl;
			return 0;
		}
		
		std::cout<<"*"<<((int)return_val)<<"_pthread  successful over"<<std::endl;//以“返回值_pthread  successful over"打印返回值
  
		return 0;
	}
private:
	static void* ZXtype_funtion(void* val)//线程的主函数(必须为void* (*)(void*)类型的普通函数,所以要用static把成员函数变成普通函数)
	{
		pthread * pthread_this=(pthread*)val;
		void *return_val=pthread_this->ZXtype_exact_funtion->exactfuntion(pthread_this->m_val);//this参数作用:找到对象本身的接受的功能对                                                                                                                //象的指针即ZXtype_exact_funtion 
		return (return_val);//返回值
	}
private:
	pthread_t n_pthread_id;
private:
	void *m_val;//传给功能函数的参数必须是公有的

};
/*=====================派生功能体(不受执行体是哪种类型都可以利用)=======================
	此功能完成i由0自增到500000,并最终打印出i的最终值与线程id。(期间用到互斥量,否则i++会在多线程中出现混乱)
*/
class myfuntion :public whatfuntion
{
public:
	myfuntion()
	{
		
	}
	~myfuntion()
	{
	
	}
protected:
	void* exactfuntion(void * w_val)	
	{
		pthread_mutex_lock(&mutex)//参数为指向互斥量的指针
		pthread_t pthreadid=pthread_self();//获取线程的id
		for(int j=5000000;j>0;j--)
		{
			(i)++;
/*注意:
互斥量保护多线程访问的共享变量(也就是全局变量,这里的局部变量j不是共享的,因为多线程访问局部变量会有自己的备份)
听说java环境下,局部结构体变量是共享的,而Linux下g++的C++没发现此问题。
互斥量必须为共享的(即全局变量)才可实现互斥
*/		}
		std::cout<<std::hex<<((int)(w_val))<<"_pthread: pth_ID="<<pthreadid<<"  ----- i="<<std::dec<<i<<std::endl;//打印传过来的参数
		pthread_mutex_unlock(&mutex);
		//sleep(3);//测试wait是否等待线程返回
		return w_val;
	}

};
/*

总结几点,

1.线程之间参数传递一定是void*型,所以传递之前必须把自己要传的参数强制转换成void*型。而且参数只能有一个,需要多个参数时可用一个结构体指针实现。

2.把执行体和功能分开可以减少两者的耦合度(也可把功能虚函数放在线程类中,在派生中重写,这就是面对对象思想,当这个功能函数只能为线程使用,而上面的接口思想可     以被任何对象使用,如进程体)

*/




                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值