共享单车(五):事件处理

具体事件处理类的基类,实现多态的接口

class iEventHandler
{
public:
    virtual iEvent* handle(const iEvent* ev) { return NULL; };
    virtual ~iEventHandler() {};
    iEventHandler(const char* name) :name_(name) {};
    std::string& get_name() { return name_; };

private:
    std::string name_;
};

根据事件类型调用不同的函数进行处理

在这里插入图片描述

// 创建完成之后先去构造函数中把他们订阅
class UserEventHandler : public iEventHandler
{
public:
    UserEventHandler();
    virtual ~UserEventHandler();
    virtual iEvent* handle(const iEvent* ev);

private:
    // 在handle内调用
    MobileCodeRspEv* handle_mobile_code_req(MobileCodeReqEv* ev);   // 验证码请求
    LoginResEv* handle_login_req(LoginReqEv* ev);   // 登录请求
    i32 code_gen(); // 生成验证码,实际中这个功能是由运营商提供的接口来实现的

private:
    //std::string mobile_;  // phone number
    std::map<std::string, i32> m2c_; //first is mobile, second is code <mobile, icode>
    pthread_mutex_t pm_;
};

构造函数中订阅,析构函数里解除绑定:

UserEventHandler::UserEventHandler() :iEventHandler("UserEventHandler")
{
	//构造函数实现订阅事件的处理
	DispatchMsgService::getInstance()->subscribe(EEVENTID_GET_MOBLIE_CODE_REQ, this);
	DispatchMsgService::getInstance()->subscribe(EEVENTID_LOGIN_REQ, this);
	thread_mutex_create(&pm_);
}

UserEventHandler::~UserEventHandler()
{
	// 析构函数实现退订事件的处理
	DispatchMsgService::getInstance()->unsubscribe(EEVENTID_GET_MOBLIE_CODE_REQ, this);
	DispatchMsgService::getInstance()->unsubscribe(EEVENTID_LOGIN_REQ, this);
	thread_mutex_destroy(&pm_);

}

根据事件类型调用不同的函数进行处理:

iEvent* UserEventHandler::handle(const iEvent* ev)
{
	if (ev == NULL)
	{
		LOG_ERROR("input ev is NULL");
		//printf("input ev is NULL");
	}

	u32 eid = ev->get_eid();

	if (eid == EEVENTID_GET_MOBLIE_CODE_REQ)
	{
		return handle_mobile_code_req((MobileCodeReqEv*)ev);
	}
	else if (eid == EEVENTID_LOGIN_REQ)
	{
		return handle_login_req((LoginReqEv*) ev);
	}
	else if (eid == EEVENTID_RECHARGE_REQ)
	{
		//return handle_recharge_req((RechargeEv*) ev);
	}
	else if (eid == EEVENTID_GET_ACCOUNT_BALANCE_REQ)
	{
		//return handle_get_account_balance_req((GetAccountBalanceEv*) ev);
	}
	else if (eid == EEVENTID_LIST_ACCOUNT_RECORDS_REQ)
	{
		//return handle_list_account_records_req((ListAccountRecordsReqEv*) ev);
	}

	return NULL;
}

处理手机验证码请求:

//短信验证码请求处理函数,接收短信验证码请求类,处理并返回短信验证码响应类
MobileCodeRspEv* UserEventHandler::handle_mobile_code_req(MobileCodeReqEv* ev)
{
	i32  icode = 0;
	std::string mobile_ = ev->get_mobile();
	LOG_DEBUG("try to get moblie phone %s validate code .", mobile_.c_str());
	printf("try to get moblie phone %s validate code .\n", mobile_.c_str());

	icode = code_gen();
	thread_mutex_lock(&pm_);	//被线程池调用,锁住临界资源
	m2c_[mobile_] = icode;
	thread_mutex_unlock(&pm_);
	LOG_DEBUG("mobile: %s, code: %d\n", mobile_.c_str(), icode);
	printf("mobile: %s, code: %d\n", mobile_.c_str(), icode);

	return new MobileCodeRspEv(ERRC_SUCCESS, icode);
}

相关知识

完整的线程池由两个部分组成,分别是存放任务的任务队列,用来放置需要处理的任务,以及处理任务的线程池,由多个线程组成,用来处理任务。

在线程池创建后,启动多个线程,绑定同一个处理函数,该处理函数的功能就是循环提取任务队列中的任务进行处理。在提取任务时,需要对任务队列进行操作,但因为任务队列是共享资源,所以线程在操作它时,需要进行线程间的同步互斥。这一点通过互斥锁与条件变量完成。

多线程的好处:
1.使用线程可以把占据时间长的程序中的任务放到后台去处理。
2.用户界面更加吸引人,这样比如用户点击了一个按钮去触发某件事件的处理,可以弹出一个进度条来显示处理的进度。
3.程序的运行效率可能会提高。
4.在一些等待的任务实现上如用户输入,文件读取和网络收发数据等,线程就比较有用了。

多线程的缺点:
1.如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换。
2.更多的线程需要更多的内存空间。
3.线程中止需要考虑对程序运行的影响。
4.通常块模型数据是在多个线程间共享的,需要防止线程死锁情况的发生。

pthread_mutex_lock 函数是一个线程同步函数,用于对互斥锁进行加锁操作。它阻塞调用线程,直到可以获得互斥锁为止。如果互斥锁已经被其他线程锁定,则调用线程将被阻塞,直到互斥锁被解锁。

如果 mutex 指向的互斥锁当前没有被锁定,则调用线程将获得锁,并继续执行。如果 mutex 指向的互斥锁已经被其他线程锁定,则调用线程将被阻塞,直到互斥锁被解锁。

互斥锁(Mutex):
把共享资源包裹起来,确保任何时候只有一个线程可以访问该资源

递归锁(Recursive Mutex):
递归锁是一种特殊的互斥锁,它允许同一线程多次对同一个锁进行锁定操作。递归锁可以用std::recursive_mutex进行实现。

独占锁(Unique Lock):
独占锁是一种智能锁,它允许程序员在控制块作用域内自动获取和释放锁。独占锁可以用std::unique_lock进行实现。

条件变量(Conditional Variable):
条件变量是一种允许线程等待特定条件的机制,直到满足某些条件才允许线程在访问共享资源之前进行访问。条件变量可以用std::condition_variable进行实现。

避免忙等待(短时间等待自旋锁,长时间等待条件变量):与忙等待(busy-waiting)相比,条件变量允许线程进入休眠状态,只有在条件满足时才会被唤醒。 避免竞争条件:条件变量通常与互斥锁(mutex)一起使用,以确保在检查条件和等待条件之间的操作是原子的。这有助于防止竞争条件(race condition)和数据竞争(data race)。

读写锁(Reader-Writer Lock):
读写锁是一种可以同时支持多个读操作和单个写操作的锁,它可以提高并发性能。读写锁可以用std::shared_timed_mutex进行实现。

添加链接描述

  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞大圣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值