首页 > 其他分享 >使用条件量和互斥锁实现线程的同步以及临界资源的互斥访问

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

时间:2024-05-31 20:44:39浏览次数:14  
标签:ts 互斥 临界 cond pthread 线程 include event



/********************************************************************
 *
 *	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

相关文章

  • 进程控制(互斥锁)
    进程控制(互斥锁)目录进程控制(互斥锁)头文件全局变量234验证头文件/********************************************************************** name :* function:主线程需要创建2个子线程之后主线程终止,此时进程中有2个子线程A和B,此时进程中有一个临界资源fag,子线程......
  • 【自定义线程池】超详细!一文轻松理解JDK线程池 - java
    【自定义线程池】超详细!一文轻松理解JDK线程池-java通过手敲一遍自定义线程池代码,轻松理解jdk中线程池的原理,可以放心告诉面试官研究过jdk线程池源码!本文参考b站黑马程序员满一航老师的JUC课程p200-208https://www.bilibili.com/video/BV16J411h7Rd?p=207&vd_sour......
  • 通过互斥锁+条件量的方式实现同步与互斥
    #include<stdio.h>#include<stdlib.h>#include<pthread.h>#include<semaphore.h>#include<unistd.h>#include<string.h>#include<fcntl.h>//forO_CREATandO_EXCL#include<sys/ipc.h>#include<sys/s......
  • 滴滴面试:谈谈你对Netty线程模型的理解?
    Netty线程模型是指Netty框架为了提供高性能、高并发的网络通信,而设计的管理和利用线程的策略和机制。Netty线程模型被称为Reactor(响应式)模型/模式,它是基于NIO多路复用模型的一种升级,它的核心思想是将IO事件和业务处理进行分离,使用一个或多个线程来执行任务的一种机制。......
  • 互斥锁练习题
    练习:设计一个程序,程序中有3个线程,主线程A创建一个文本,每隔5s获取一次系统时间并写入到该文本中,另外两个线程B和C分别从文本中读取当前的时间和日期,子线程B输出系统时间"hh:mm:ss",子线程c输出系统日期"2024年05月31日”,要求使用读写锁实现互斥。提示:主线程A获取写操作的锁,另外......
  • 关于《Java并发编程之线程池十八问》的补充内容
    一、写在开头在上一篇文章我们写《Java并发编程之线程池十八问》的时候,鉴于当时的篇幅已经过长,很多内容就没有扩展了,在这篇文章里对一些关键知识点进行对比补充。二、RunnablevsCallable在创建线程的时候,一般会选用Runnable和Callable两种方式。【源码对比】Runnable接......
  • Linux——线程(线程概念)
    目录一、细粒度划分1.1、堆区细粒度划分1.2、物理内存和可执行程序细粒度划分1.3、虚拟地址到物理地址的转化二、线程概念2.1、基本概念2.2、线程优点2.3、线程的缺点2.4、线程异常 2.5、线程用途三、Linux下的进程和线程一、细粒度划分1.1、堆区细粒度划分 ......
  • C#管理异步线程
    管理异步线程usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Threading;usingSystem.Threading.Tasks;namespacePortClient{///<summary>///异步线程///*修改为枚举类型更合理///</summary>publicstati......
  • 面试官:如果不允许线程池丢弃任务,应该选择哪个拒绝策略?
    线程池的拒绝策略有哪些?如果当前同时运行的线程数量达到最大线程数量并且队列也已经被放满了任务时,ThreadPoolExecutor定义一些策略:ThreadPoolExecutor.AbortPolicy:抛出RejectedExecutionException来拒绝新任务的处理。ThreadPoolExecutor.CallerRunsPolicy:调用执行自己的......
  • 操作系统复习:进程和线程的理解串记
    进程和线程        我是一个ikun,我坐着不动(静态)就是ikun程序,我开始执行任务唱、跳、rap和打篮球(动态)就是ikun进程。在ikun进程中,我们的孩子就是线程。        为了ikun进程们能公平地抢坤坤哥哥下的蛋(临界资源),坤坤哥哥(CPU)会安排(进程调度)时间片给每个ikun进程......