• 8.gec6818开发板通过并发多线程实现电子相册 智能家居 小游戏三合一完整项目


    并发

    前面编写的程序都是从mian函数开始,从上往下执行,称为顺序执行

    假设一个程序需要I输入 C计算 P输出,以顺序执行三个上述程序,则其执行过程如下:

    在这里插入图片描述

    程序内部的语句是一条一条的执行,如果要运行多个程序,这些程序也是一个一个的依次执行,若上述的三种操作,每种操作需要的时间都是t,则执行上述三个程序共需要9t

    而在上述程序的执行过程中,只有计算需要用到cpu==》CPU的利用率只有 3t/9t = 33.33%

    顺序执行的CPU利用率太低

    有没有办法提高CPU利用率呢?

    ==》并发

    1.并发执行

    并发 指的是同一时间内,同时处理多个任务的机制

    我们现在的操作系统几乎都支持并发执行,并且提供并发的实现机制==》Linux并发进程和并发线程

    所谓并发是指多个任务在“同一时间”被处理==》“同一时间”:指的是一段时间而不是某个时间点

    (同一时间点有多个任务同时被处理,称之为并行,多核cpu的实现)

    并发执行的实现是将一个任务按其功能分为多个阶段,并且不同的阶段有不同的组件去完成,因此当一个任务在执行其中的某个功能的时候,其他组件可以去执行另外的已经就绪的功能

    在这里插入图片描述

    原本需要9t才能完成的任务,此时只需要5t,意味着CPU的利用率达到了3T/5T=60%有效的提高了CPU的利用率

    2.Linux线程并发的实现

    线程是指在一个程序执行过程中开辟多条执行分支去同时处理不同的任务的一种机制

    “执行分支”就是所谓的线程

    在这里插入图片描述

    程序在运行时,从mian函数开始执行的分支称为主线程,主线程是程序程序执行的伊始,同时一旦主线程执行结束,整个程序也就结束了,不管其他的分支线程是否执行完成,都会随着主线程一起结束

    如何在程序执行过程中,创建新的执行分支线程呢

    创建线程

    Linux中的线程是采用POSIX提供的接口来创建和维护,因此需要引用头文件pthread.h ,同时在编译时需要链接POSIX库

    即我们编译时要加上-pthread

    创建线程是通过调用下列函数来实现

    NAME
           pthread_create - create a new thread
    
    SYNOPSIS
           #include 
    			pthread_create用来创建一个新的线程
           int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                              void *(*start_routine) (void *), void *arg);
    		@thread:指针指向一个pthread_t类型的变量,用来存储线程的编号(线程号)
            @attr:指定线程属性,一般为NULL
            @start_routine:函数指针,指向一个返回值为void*,参数为void*的函数,是用来指定新创建的线程需要执行的函数
            @arg:void*指针,指向用于传递给线程函数的参数
            返回值:成功是0
                   失败返回一个!0值,是函数调用失败的错误编码
           Compile and link with -pthread.
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注意:如果在一个程序执行过程中创建了线程,则主线程和分支线程是“同时”执行的

    例如:

    在一个程序中,创建两个执行分支,其中

    1.主分支不断输出’hello"

    2.1号分支不断输出"nihao"

    3.2号分支不断输出一个"gun"

    顺序执行的结果

    在这里插入图片描述

    #include 
    #include 
    #include 
    
    
    void* thread_function1(void*arg)
    {
    	while(1)
    	{
    		printf("nihao\n");
    		sleep(1);
    	}
    }
    
    void* thread_function2(void*arg)
    {
    	while(1)
    	{
    		printf("gun\n");
    		sleep(1);
    	}
    } 
    
    int main (void)
    {
    	thread_function1(NULL);
    	thread_function2(NULL);
    
    	while(1)
    	{
    		printf("hello\n");
    		sleep(1);
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    通过线程方式实现

    在这里插入图片描述

    #include 
    #include 
    #include 
    
    
    void* thread_function1(void*arg)
    {
    	while(1)
    	{
    		printf("nihao\n");
    		sleep(1);
    	}
    }
    
    void* thread_function2(void*arg)
    {
    	while(1)
    	{
    		printf("gun\n");
    		sleep(1);
    	}
    } 
    
    int main (void)
    {
    	//thread_function1(NULL);
    	//thread_function2(NULL);
    	pthread_t tid1,tid2;
    	int ret = 0;
    	ret = pthread_create(&tid1, NULL,thread_function1, NULL);//创建一个线程去执行thread_function1函数,并且传递的参数为NULL
    	if (0 != ret)
    	{
    		printf("pthread1 create error:%d\n",ret );
    	}
    	
    	ret = pthread_create(&tid2, NULL,thread_function2, NULL);//创建一个线程去执行thread_function1函数,并且传递的参数为NULL
    	if (0 != ret)
    	{
    		printf("pthread1 create error:%d\n",ret );
    	}
    
    
    	while(1)
    	{
    		printf("hello\n");
    		sleep(1);
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    上述案例中创建了两个分支线程+主线程 总共有三个线程在同时执行,因此可以同时处理三个死循环的任务

    并且:虽然三个线程执行的是不同的代码,但是都处于一个程序中,他们可以访问相同的全局变量

    任务:

    在项目中创建多个线程,让不同的线程去完成不同的工作,并且与你设计的初始界面的按键相匹配

    1.电子相册

    2.GY-39数据的采集,并将数据保存在全局变量中

    3.高温报警器

    4.将全局变量中的数据显示到LCD屏幕中

    5.小游戏

    主线程负责获取触摸屏的输入事件来实现人机交互

    个线程执行的是不同的代码,但是都处于一个程序中,他们可以访问相同的全局变量

    任务:(电子相册 智能家居 小游戏三合一项目 需要私信我)

    在项目中创建多个线程,让不同的线程去完成不同的工作,并且与你设计的初始界面的按键相匹配

    1.电子相册

    2.GY-39数据的采集,并将数据保存在全局变量中

    3.高温报警器

    4.将全局变量中的数据显示到LCD屏幕中

    5.小游戏

    主线程负责获取触摸屏的输入事件来实现人机交互

    在这里插入图片描述

  • 相关阅读:
    neon常用指令(updating)
    计算机毕业设计之java+springboot基于vue的网上书城管理系统
    WEB开发技能树-PHP-GET/POST传参方式
    工业5G路由器驱动矿山无人值守及井下监控数据传输
    Rsync 与frp搭建远程备份服务和基本命令行操作示例
    【Python】Java工程师学Python之PyCharm安装详细教程
    【ROS 2 基础-常用工具】-6 Rviz基础使用
    机器学习笔记:RNN值Teacher Forcing
    js如何判断设备类型(是否可以触屏)
    【MongoDB 新搭档 Kafka】
  • 原文地址:https://blog.csdn.net/xqmids99/article/details/133086806