多线程实现电子相框输入

多线程输入基本框架

初始化时,创建子线程;主线程调用休眠函数进入休眠状态,等待被子线程唤醒;子线程中,分别调用各个设备的事件函数,随即各个子线程进入休眠状态;当输入事件发生的时候,唤醒子线程,子线程唤醒主线程;在主线程中对事件进行处理。

在原先实现查询方式的工程中修改:
input_manager.c中:

  • 创建主线程休眠函数,有之前程序的事件处理函数修改;
  • 初始化函数中创建子线程;
  • 创建子线程函数;

设备应用程序中:

  • 之前在qurey和select方式中,等待事件发生的状态都属于非阻塞方式,也就是没有事件发生也返回;但是为了让子线程进入休眠状态,现在让等待事件发生的状态都改为阻塞方式,也就是除非有事件发生,否则都处于休眠状态。
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict_attr,
					void*(*start_rtn)(void*),void *restrict arg);

第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。如果设置为NULL则按照默认设置。
第三个参数是线程运行函数的地址。线程从这个函数开始执行。void*(*start_rtn)(void*)这种写法表示start_rtn为一个函数指针,该指针指向的函数返回的是一个void型的指针。
最后一个参数是线程运行函数的参数。可以设置成一个函数指针,不过在调用函数指针的时候必须要进过强制类型转换,将指针转化成目标调用函数类型。在此最后一个参数传入了事件处理函数的指针。

pthread_create(&ptTemp->tInfo,NULL,StartRoutine,ptTemp->InputDevEventIdel);
/*创建一个子线程,并跳转到StartRoutine执行*/

这个函数在初始化函数中实现,每对一个设备进行初始化,就创建一个线程。

PS:调用线程相关函数,由于线程库不是linux标准库文件,因此在编译的时候需要链接静态库。

LDFLAGS := -lm -lfreetype -lts -lpthread

以上程序涉及到多线程之间通信,常见的通信方式如互斥锁、条件变量、信号、读写锁等。
在此采用的主要是条件变量。在此参考了深入解析条件变量

int GetInputEvent(PT_InputEventOpr ptInputEvent)/*事件处理,或者叫事件查询*/
{
	pthread_mutex_lock(&g_Mutex);/*获取互斥量*/
	
	pthread_cond_wait(&g_Condvar,&g_Mutex);/*设置条件变量处于等待状态*/
	*ptInputEvent=g_tInputEventOpr;

	pthread_mutex_unlock(&g_Mutex);/*施放互斥量*/

	return 0;
}

pthread_cond_wait执行过程中,首先将线程放置在等待队列当中,同时施放互斥锁,以方便其他线程(或者叫生产者线程\子线程)对条件变量进行修改。但是要注意的是,执行到此函数的时候线程会发生pending;当生产者线程发出信号之后,pthread_cond_wait解除拥塞,获取互斥锁,对生产者产生的数据进行处理。

void* StartRoutine(void *pvTemp)
{
	int (*InputDevEventIdel)(PT_InputEventOpr);
	/*定义一个函数指针,返回值是int,参数是PT_InputEventOpr*/
	InputDevEventIdel = (int(*)(PT_InputEventOpr))pvTemp;

	while(1)
	{
		//pthread_mutex_lock(&g_Mutex);
		/*显然不能放在这个位置,此处事件未发生,易造成信号丢失*/
		if(0==InputDevEventIdel(&g_tInputEventOpr))
		{
			pthread_mutex_lock(&g_Mutex);
			pthread_cond_signal(&g_Condvar);
			pthread_mutex_unlock(&g_Mutex);
		}
	}
	return NULL;
}

关于为什么需要将条件变量与互斥锁一起使用:条件变量g_Condvar属于全局变量,要对它进行修改本身就需要加锁;消费者线程进入pending的时候,pthread_cond_wait会把锁释放,以使得条件变量可修改,生产者线程如果想要调用pthread_cond_signal发出信号,首先如要获取锁,这样尽可能的防止了信号丢失的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值