/*******************************************************************
* author : 北极甜虾呦
* date : 2024/06/01
* function : 进程中使用条件量和互斥锁实现线程的同步以及临界资源的互斥访问
* note : None
* CopyRight (c) 2023-2024 [email protected] All Right Reseverd
*
* *****************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h> //触摸屏必须包含该头文件
int x,y;
int ts_fd;
//临界资源,应该使用volatile进行修饰,防止编译器对该变量进行优化
volatile int flag = 0;
//初始化互斥量和条件量
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int ts_x, ts_y;
//声明触摸函数
void ts_getval(int ts_fd,int *ts_x,int *ts_y);
//子线程A
void *task_A(void *arg)
{
while(1)
{
//获取触摸的函数
ts_getval(ts_fd,&ts_x,&ts_y);
//上锁
pthread_mutex_lock(&mut);
//判断触摸的位置
if(x>0 && x<100 && y>0 && y<100)
{
flag = 1;//设置临界资源的值
}
//唤醒子进程B
pthread_cond_broadcast(&cond);
x = 0;
y = 0;
//解锁
pthread_mutex_unlock(&mut);
}
}
//子线程B
void *task_B(void *arg)
{
while(1)
{
//上锁
pthread_mutex_lock(&mut);
//如果满足此条件则子线程B挂起(睡眠),此时会自动解锁,不会往下执行
while(flag == 0){
pthread_cond_wait(&cond, &mut);
}
//满足此条件则打印字符串
if (flag > 0) {
printf("I am thread_B,str = [%s]\n","hello world");
flag = 0;//复位flag的值
}
//解锁
pthread_mutex_unlock(&mut);
}
}
int main()
{
//1.打开触摸屏
ts_fd = open("/dev/input/event0",O_RDWR);
if (-1 == ts_fd)
{
fprintf(stderr, "open ts error,errno:%d,%s\n",errno,strerror(errno));
return -1;
}
//1.创建子线程A
pthread_t thread_A;
pthread_create(&thread_A,NULL,task_A,NULL);
//2、创建子线程B
pthread_t thread_B;
pthread_create(&thread_B,NULL,task_B,NULL);
//3、终止主线程
pthread_exit(NULL);
while(1);
return 0;
}
void ts_getval(int ts_fd,int *ts_x,int *ts_y)
{
int cnt = 0;
//1.读取输入设备的信息
struct input_event ts_event;
//2.循环获取坐标,当获取到完整坐标(x,y)则终止循环
while(1)
{
//read函数默认会阻塞的,也就是没有读取数据,则卡这句话
read(ts_fd,&ts_event,sizeof(ts_event));
//3.分析读取的设备信息 (type + code + value)
if (ts_event.type == EV_ABS && ts_event.code == ABS_X) //说明是触摸屏X轴
{
cnt++;
*ts_x = ts_event.value * 800 / 1024;
}
if (ts_event.type == EV_ABS && ts_event.code == ABS_Y) //说明是触摸屏Y轴
{
cnt++;
*ts_y = ts_event.value * 480 / 600;
}
//如果获取完整坐标,则输出获取的坐标用于项目测试
if(cnt >= 2)
{
x = *ts_x;
y = *ts_y;
printf("x = %d\t",x); //输出X轴坐标
printf("y = %d\n",y); //输出Y轴坐标
break;
}
}
}
标签:int,ts,互斥,临界,线程,pthread,include,event
From: https://www.cnblogs.com/lwj294/p/18225620