目录
title: 多输入使用多线程
date: 2019/3/20 19:27:05 toc: true ---多输入使用多线程
这里有份英文文档,很详细的说明
具体的手册在man3 搜索pthread
完整的pdf在 Unix_Linux_Windows_OpenMP多线程编程.pdf
代码仓库
常用函数
头文件 #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个等待的线程 |
简单使用
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); }}
引入电子书
- 设置两个输入都为阻塞方式,这样没有输入的时候都会休眠了
- 主函数调用A()来获取输入
- A()就是主线程了,使用条件变量
pthread_cond_wait
等待唤醒 - B()为线程函数,具体调用的就是输入的阻塞输入,有数据后唤醒线程后再去唤醒主线程
// 主线程查询函数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;}
滑屏
滑动屏幕来达到翻页
思路: 记录第一次按下的位置,记录松开的位置,计算差值