使用条件量和互斥锁实现线程的同步以及临界资源的互斥访问



/********************************************************************
 *
 *	name	 :
 *	function :主线程需要创建2个子线程之后主线程终止,此时进程中有2个子线程A和 B,此时进程中有一个临界资源 fag,子线程A获取触摸屏坐标并判断坐标值是否在LCD屏的左上角,如果坐标范围满足左上角,则利用条件量和互斥锁来唤醒子线程B,子线程B的任务是判断fag 是否大于 0,如果子线程B的条件满足,则让子线程B在终端输出一个字符串即可。要求进程中使用条件量和互斥锁实现线程的同步以及临界资源的互斥访问
 *	argument :
 *				@n  :需要计算的值n
 *
 *	retval	 :
 *	author	 :  1810866453@163.com
 *	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	 :  1810866453@163.com
 *	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	 :  1818066453@163.com
 *	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;
}
posted @   Zeratul$$$  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示