多输入使用多线程

多输入使用多线程

https://computing.llnl.gov/tutorials/pthreads/ 这里有份英文文档,很详细的说明

具体的手册在man3 https://linux.die.net/man/3/ 搜索pthread

完整的pdf在 Unix_Linux_Windows_OpenMP多线程编程.pdf

代码仓库 https://gitee.com/layty/project_for_linux/tree/master/03-ebook/05_input_by_pthread

常用函数

头文件 #include <pthread.h>

POSIX 函数 描述
pthread_cancel 终止另一个线程
pthread_create 创建一个线程
pthread_detach 设置线程以释放资源
pthread_equal 测试两个线程 ID 是否相等
pthread_exit 退出线程,而不退出进程
pthread_join 等待一个线程
pthread_self 找出自己的线程 ID
互斥锁线程控制
pthread_mutex_init 互斥锁初始化
pthread_mutex_lock 互斥锁上锁 ,默认是会阻塞的
pthread_mutex_trylock 互斥锁判断上锁
pthread_mutex_unlock 互斥锁接锁
pthread_mutex_destroy 消除互斥锁
信号量线程控制
sem_init 创建一个信号量,并初始化它的值
sem_wait 将信号量的值减一,<0将会阻塞进程
sem_trywait 将信号量的值减一,<0会立即返回
sem_post 将信号量的值加一同时发出信号来唤醒等待的进程
sem_getvalue 得到信号量的值
sem_destroy 删除信号量
线程属性
绑定属性 保证在需要的时候总有一个内核线程与之对应
分离属性 它终止以后就可能将线程号和系统资源移交给其他的程使用,这时调用pthread_create()的线程就得到了错误的线程号
pthread_attr_init 初始化
pthread_attr_setscope 设置绑定属性
pthread_attr_setdetachstate 设置分离属性
pthread_attr_setschedparam 设置线程优先级
pthread_attr_destroy 对分配的属性结构指针进行清理和回收
相应函数获取属性
条件变量
pthread_cond_init 初始化
pthread_cond_destroy 销毁
pthread_cond_timedwait 等待,含超时
pthread_cond_wait 一直等待, 等待的时候会释放互斥量
pthread_cond_broadcast 唤醒所有等待的线程
pthread_cond_signal 唤醒1个等待的线程

mark

mark

简单使用

void *thrd_func(void *arg)
{
....
    pthread_exit(NULL);
}

int main(void)
{
    #define THREAD_NUMBER 1 /*线程数*/
	pthread_t thread[THREAD_NUMBER];
    
    /* 创建多线程 */
    no = 0;
	res = pthread_create(&thread[0], NULL, thrd_func, (void*)no);
    
    
    res = pthread_join(thread[0], &thrd_ret);
    if (!res)
    {
    	printf("Thread %d joined\n", no);
    }
    else
    {
    	printf("Thread %d join failed\n", no);
    }
}

引入电子书

  1. 设置两个输入都为阻塞方式,这样没有输入的时候都会休眠了
  2. 主函数调用A()来获取输入
  3. A()就是主线程了,使用条件变量pthread_cond_wait等待唤醒
  4. B()为线程函数,具体调用的就是输入的阻塞输入,有数据后唤醒线程后再去唤醒主线程

mark

// 主线程查询函数
int GetInputEvent(T_InputEvent * out)
{
	pthread_mutex_lock(&g_mutex);
	
	pthread_cond_wait(&g_tConVar, &g_mutex);	
	/* 被唤醒后,返回数据 */
	*out = g_Input_Event_val;
	pthread_mutex_unlock(&g_mutex);
	return 0;

}


//创建的子线程
int AllInputDevicesInit(void)
{
	T_InputOp* now=T_InputOp_list;
	int iError = -1;
	

	while (now)
	{
		if (0 == now->Init())
		{
			/* 创建子线程 */
			pthread_create(&now->thread_id, NULL, GetInputThreadFun, now->GetInputEventOp);	
			iError = 0;
		}
		now = now->next;
	}
	return iError;
}

// 具体的子线程函数
static void * GetInputThreadFun(void *fun)
{
	T_InputEvent out_tmp;
	
	int (*ThisGetInputEventOp)(T_InputEvent* )=(int (*)(T_InputEvent* ))fun;
	
	while (1)
	{
		if(0 == ThisGetInputEventOp(&out_tmp))
		{
			/* 唤醒主线程, 把tInputEvent的值赋给一个全局变量 */
			/* 访问临界资源前,先获得互斥量 */
			pthread_mutex_lock(&g_mutex);
			g_Input_Event_val = out_tmp;

			/*  唤醒主线程 */
			pthread_cond_signal(&g_tConVar);

			/* 释放互斥量 */
			pthread_mutex_unlock(&g_mutex);
		}
	}
	return NULL;
}

滑屏

滑动屏幕来达到翻页

思路: 记录第一次按下的位置,记录松开的位置,计算差值

posted @ 2019-03-21 20:32  zongzi10010  阅读(427)  评论(0编辑  收藏  举报