/********************************************************************
*
* name :
* function :主线程需要创建2个子线程之后主线程终止,此时进程中有2个子线程A和 B,此时进程中有一个临界资源 fag,子线程A获取触摸屏坐标并判断坐标值是否在LCD屏的左上角,如果坐标范围满足左上角,则利用条件量和互斥锁来唤醒子线程B,子线程B的任务是判断fag 是否大于 0,如果子线程B的条件满足,则让子线程B在终端输出一个字符串即可。要求进程中使用条件量和互斥锁实现线程的同步以及临界资源的互斥访问
* argument :
* @n :需要计算的值n
*
* retval :
* author : [email protected]
* date : 2024年5月31日
* note :
* *****************************************************************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <sys/ipc.h>
#include <linux/input.h>
#include <sys/mman.h> //映射功能
volatile int fag = 0, cnt, x, y, a; // 临界资源 fag,cnt,x,y
int *lcd_mp; // lcd映射
int lcd_fd, ts_fd; // lcd和触摸屏
struct input_event ts_event; // 触摸信息存放
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 条件量
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
sem_t *sem;
/********************************************************************
*
* name :funcA
* function :获取触摸屏坐标并判断坐标值是否在LCD屏的左上角,如果坐标范围满足左上角,则利用条件量和互斥锁来唤醒子线程B
* argument :
* @n :需要计算的值n
*
* retval :pthread_cond_broadcast pthread_cond_destroy
pthread_cond_init pthread_cond_signal
pthread_cond_timedwait pthread_cond_wait
* author : [email protected]
* date : 2024年5月31日
* note :
*
* *****************************************************************/
void *funcA(void *arc)
{
pthread_mutex_lock(&mut);
for (;;)
{ // read函数默认会阻塞的,也就是没有读取数据,则卡这句话
read(ts_fd, &ts_event, sizeof(ts_event));
// 3.分析读取的设备信息 (type + code + value)
if (ts_event.type == EV_ABS) // 说明是触摸屏
{
if (ts_event.code == ABS_X) // 说明是X轴
{
cnt++;
x = ts_event.value * 800 / 1024;
}
if (ts_event.code == ABS_Y) // 说明是Y轴
{
cnt++;
y = ts_event.value * 480 / 600;
}
// 在屏幕左上角
if (cnt >= 2 && x > 0 && x < 100 && y > 0 && y < 100)
{
fag = 3;
}
printf("唤醒\n");
// 唤醒B
pthread_cond_signal(&cond);
// 还锁
pthread_mutex_unlock(&mut);
}
}
}
/********************************************************************
*
* name :funcB
* function :
* argument :判断fag 是否大于 0,如果子线程B的条件满足,则让子线程B在终端输出一个字符串
* @n :需要计算的值n
*
* retval :
* author : [email protected]
* date : 2024年5月31日
* note :
*
* *****************************************************************/
void *funcB(void *arc)
{
for (;;)
{
pthread_mutex_lock(&mut);
if (fag == 3)
{
pthread_cond_wait(&cond, &mut);
printf("hello world\n");
fag = 0;
}
// sleep(3);
pthread_mutex_unlock(&mut);
}
}
int main(int argc,
char const *argv[])
{
// 1.打开LCD open
lcd_fd = open("/dev/fb0", O_RDWR);
// 2.对LCD进行内存映射 mmap
lcd_mp = (int *)mmap(NULL,
800 * 480 * 4,
PROT_READ | PROT_WRITE, MAP_SHARED,
lcd_fd, 0);
ts_fd = open("/dev/input/event0", O_RDWR);
// 创建两个线程
pthread_t Afunc;
pthread_t Bfunc;
pthread_create(&Afunc, NULL, funcA, NULL);
pthread_create(&Bfunc, NULL, funcB, NULL);
// 初始化
pthread_cond_init(&cond, NULL);
// 结束主进程
pthread_exit(NULL);
return 0;
}
标签:ts,互斥,临界,cond,pthread,线程,include,event
From: https://www.cnblogs.com/zeratul/p/18225254