2嵌入式系统设计实验二(多线程)
《嵌入式软件设计》实验报告-多线程程序设计
![《嵌入式软件设计》实验报告-多线程程序设计](https://img.taocdn.com/s3/m/74c9c5c5050876323112128c.png)
2.运行make产生pthread可执行文件。
3.切换到minicom终端窗口,使用NFS mount开发主机的/up-techpxa270到/mnt目录。
4.进入/mnt/exp/basic/pthread目录,运行./pthread,观察运行结果的正确性,若显示结果太快,可以用以下命令输出显示结果到pthread.txt文件./pthread >pthread.txt,然后再用cat pthread.txt察看文件内容,结合程序分析结果。
5.修改一些参数(比如1000、BUFFER_SIZE),再次运行调试,加深对多线程的理解。
6.加入一个新的线程用于处理键盘的输入,并在按键为ESC时终止所有线程。
四、实验结果
五、教师评语
签名:
日期:
成绩
《嵌入式系统软件设计》实验报告
实验序号:03实验项目名称:多线程程序设计
学 号
1007012141
姓 名
黄丽金
专业、班
10计算机1班
实验地点
实3-26
一、实验目的
1.了解多线程程序设计的基本原理。
2.学习pthread库函数的使用。
二、实验设备(环境)及要求
硬件:PC机;PXA270试验箱
软件:PC机操作系统linux
三、实验内容与步骤
读懂pthread.c的源代码,熟悉几个重要的PTHREAD库函数的使用。掌握共享锁和信号量的使用方法。进入/up-techpxa270/exp/basic/02_pthread目录,运行make产生pthread程序,使用NFS方式连接开发主机进行运行实验。
多线程程序实验报告(3篇)
![多线程程序实验报告(3篇)](https://img.taocdn.com/s3/m/cb15f73576232f60ddccda38376baf1ffc4fe3b0.png)
第1篇一、实验目的1. 理解多线程的概念和作用。
2. 掌握多线程的创建、同步和通信方法。
3. 熟悉Java中多线程的实现方式。
4. 提高程序设计能力和实际应用能力。
二、实验环境1. 操作系统:Windows 102. 开发工具:IntelliJ IDEA3. 编程语言:Java三、实验内容本次实验主要完成以下任务:1. 创建多线程程序,实现两个线程分别执行不同的任务。
2. 使用同步方法实现线程间的同步。
3. 使用线程通信机制实现线程间的协作。
四、实验步骤1. 创建两个线程类,分别为Thread1和Thread2。
```javapublic class Thread1 extends Thread {@Overridepublic void run() {// 执行Thread1的任务for (int i = 0; i < 10; i++) {System.out.println("Thread1: " + i);}}}public class Thread2 extends Thread {@Overridepublic void run() {// 执行Thread2的任务for (int i = 0; i < 10; i++) {System.out.println("Thread2: " + i);}}}```2. 创建一个主类,在主类中创建两个线程对象,并启动它们。
```javapublic class Main {public static void main(String[] args) {Thread thread1 = new Thread1();Thread thread2 = new Thread2();thread1.start();thread2.start();}```3. 使用同步方法实现线程间的同步。
```javapublic class SynchronizedThread extends Thread {private static int count = 0;@Overridepublic void run() {for (int i = 0; i < 10; i++) {synchronized (SynchronizedThread.class) {count++;System.out.println(Thread.currentThread().getName() + ": " + count);}}}}public class Main {public static void main(String[] args) {Thread thread1 = new SynchronizedThread();Thread thread2 = new SynchronizedThread();thread1.start();thread2.start();}```4. 使用线程通信机制实现线程间的协作。
嵌入式多线程 实习总结(有感想)
![嵌入式多线程 实习总结(有感想)](https://img.taocdn.com/s3/m/2092eeca4028915f804dc2b4.png)
解压应用程序以及多线程应用程序设计实习过程首先完成上次实习没有完成的解压应用程序的部分。
设置好宿主机和目标机的IP地址后,运行FTP软件。
将压缩包从右侧的宿主机本地目录“拖到”左侧的目标机目录中。
最后在超级终端上完成解压。
其次完成多线程的部分,运行虚拟机后,步骤如下:1、挂载NFS服务。
系统设置部分需要完成关闭防火墙,设置宿主机和目标机IP(需在一个网段内),配置NFS服务器。
之后:service nfs start。
启动。
挂载NFS时候出现了问题。
当设置宿主机IP为192.168.1.155之后,在虚拟机的LINUX终端里mount了192.168.1.155(也就是自己挂载自己),然后总感觉不对,鼓捣了半天,又在超级终端里ifconfig之后出现了三个IP地址,第一个是inet addr,第二个是broadcast,第三个是子网掩码,但是我当时没看懂第二个地址,于是又把宿主机的IP设置为了192.168.1.255。
老师一说才想起来计算机网络课上讲的,C类的网络地址,后8位若为全1,应该是广播地址才对。
反正这块乱了。
分析后,觉得主要原因还是因为对挂载的深层含义不懂,没明白其实是目标机想要宿主机里的东西,所以要从超级终端里挂载host下的目录。
最终完成挂载。
Mount –t nfs 192.168.0.2:/arm2410cl/ /mnt/nfs (老师说这里直接写/mnt不好,会覆盖掉mnt目录,如果以后要挂载其他的应用,就不好弄了。
)2、第一步成功后,在超级终端上cd arm2410cl/exp/basic/02_pthread。
成功进入,make语句后,用命令:./pthread成功运行。
3、在虚拟机的LINUX终端上,也进入了arm2410cl/exp/basic/01_hello,但是不能运行hello,用gcc hello.c –o hello之后,./hello就能运行了。
用这个方法,完成02_pthread,发现gcc提示几个相似错误,都跟main函数里的一个函数有关。
《嵌入式系统》实验报告指导书(含答案).
![《嵌入式系统》实验报告指导书(含答案).](https://img.taocdn.com/s3/m/14ee1ee9240c844769eaeec3.png)
实验一熟悉嵌入式LINUX开发环境1、实验目的熟悉UP-TECHPXA270-S的开发环境。
学会WINDOWS环境与嵌入式Linu环境共享资源的基本方法。
2、实验内容学习UP-TECHPXA270-S系统的使用、XP和虚拟机之间传送文件方法以及UP-TECHPXA270-S和虚拟机之间共享目录的建立方法。
3、预备知识了解UP-TECHPXA270-S的基本结构和配置,Linux基本知识。
4、实验设备硬件:UP-TECHPXA270-S开发板、PC机(内存500M以上)。
软件:PC机操作系统RADHAND LINUX 9+MIMICOM+RAM LINUX操作系统5、实验步骤(1)、在虚拟机下练习Linux常用命令。
(注意以下操作只能在[root@BC root]#,也就是root文件夹下运行,不然会导致系统不能启动)a. 学习命令通过“man ***”和“*** --help”得到的命令使用方法。
b.学习并掌握如下命令:ls,cd ,pwd,cat,more,less,mkdir, rmdir ,rm,mv,cp,tar,ifconfig(2)、XP与虚拟机之间传送文件(Samba服务器建立、网络设置、文件传送);(3)、了解系统资源和连线;(4)、开发板与虚拟机之间共享目录建立(设置NFS、开发板IP设置、目录挂载),挂载文件;(5)vi(vim)的使用(6)输入qt,启动桌面,按CTRL+C退出6、实验报告要求(1)、XP和虚拟机之间传送文件步骤;虚拟机共享XP文件:选择虚拟机设置,设置要共享的文件启动Linux进入/mnt/hgfs即可看到共享文件夹服务器设置——samba服务器(设置需要共享的目录)XP共享虚拟机文件:服务器设置——samba服务器(设置需要共享的目录)确保网络的PING通(即在同一局域网):1.虚拟机的192.168.1.234(RH9)2.XP的为192.168.1.1253.在XP 下点击开始-》运行(\\192.168.1.234)4.用户名bc密码123456以上实现了Linux虚拟机(RH9)和XP的文件的共享(2)、开发板与虚拟机之间建立共享目录以及文件挂载步骤;1.服务器设置——nfs服务器(设置需要共享的目录)2.设置开发板的ip地址:ifconfig eth0 192.168.1.53.在实验箱终端里输入mount -t nfs -o nolock 192.168.1.234:/up-techpxa270/exp /mnt/nfs4./mnt/nfs即为共享目录(3)、请画出虚拟机、PC机和ARM实验箱之间的硬件连接图;(4)、在Linux中怎样配置网络;系统设置->网络,在新的选项卡中(5)、实验中遇到的问题与解决过程。
北邮嵌入式系统设计实验-实验报告
![北邮嵌入式系统设计实验-实验报告](https://img.taocdn.com/s3/m/05aff8b7d1f34693daef3e5b.png)
嵌入式实验报告学院:xxx班级:xxx学号:xxx姓名:xxx成员:xxx一、基础知识部分1.多线程实验本章主要讲解线程的概念和线程间的同步方式。
实验一主要介绍线程的概念和线程的创建,实验二、实验三、实验四分别介绍了信号量、互斥锁、条件变量的作用和使用。
1.1 线程的介绍线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。
线程是程序中一个单一的顺序控制流程。
进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。
在单个程序中同时运行多个线程完成不同的工作,称为多线程。
线程是允许应用程序并发执行多个任务的一种机制,是程序运行后的任务处理单元,也是SylixOS操作系统任务调度的最小单元。
在多核CPU中,同时可以有多个线程在执行,实现真正意义上的并行处理。
线程入口函数是一个能够完成特定任务的函数,因此线程入口函数的编写上与普通函数没有太多区别。
线程的创建函数如下:●创建线程失败,函数返回非0的错误代码,成功返回0;●*thread pthread_t类型的缓冲区,保存一个线程的线程ID;●*attr 设置线程属性,设置为NULL标识创建的新线程使用默认属性;●*(*start_routine) 线程入口函数函数名●*arg 向所创建线程传入的参数1.2 信号量的概念信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。
在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。
其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。
信号量是一个在进程和线程中都可以使用的同步机制。
信号量类似于一个通知,某个线程发出一个通知,等待此通知的线程收到通知后,会执行预先设置的工作。
当接收通知的线程没有收到通知前,会处于阻塞状态。
实验二 多线程应用程序设计
![实验二 多线程应用程序设计](https://img.taocdn.com/s3/m/5d0b7cea3b3567ec102d8afd.png)
成绩信息与通信工程学院实验报告课程名称:嵌入式系统原理与应用实验题目:多线程应用程序设计指导教师:班级:学号:学生:一、实验目的和任务1.掌握VI编译环境。
2.掌握GCC编译命令。
3.掌握多个文件共同编译方法。
4.掌握GDB调试命令。
5.了解多线程程序设计的基本原理。
6.学习pthread 库函数的使用。
二、实验设备7.硬件:PC机8.软件:LINUX操作系统、虚拟机三、实验容及原理1.在VI编辑器里编写两个文件(其中一个为主程序,实现显示“hello,linux world,Iam 1405014XXX XXX”,,一个为子程序,实现1~n的乘法),为其书写头文件,共同编译为可执行文件,执行,观察运行结果。
学习书写MAKEFILE文件,编译,执行,观察结果。
利用GCC 编译(加参数-g)为可执行文件,利用GDB调试,学习GDB 调试命令。
2.编写多线程程序设计。
编译并运行,观察结果。
(可参照课件或实验指导书)四、实验步骤或程序流程1.Gcc编译实验1)编写实验代码:图3.1实验主程序图3.2实验子程序2)编写Makefile文件:图3.3 Makefile文件3)Make执行Makefile文件,生成可执行程序并运行:图3.4 执行4)Gdb调试运行:图3.5 gdb调试显示代码图3.6 gdb调试断点运行图3.7 gdb调试逐步运行2.多线程程序设计:1)对实验代码进行gcc编译:图3.7gcc编译生成可执行文件2)运行结果:图3.8程序运行结果五、实验数据及程序代码1.Gcc编译实验:1)主程序:#include "stdio.h"#include "my2.h"int main(){printf("hello.Linux world.I am 1405014232 zzm\n");my2();}2)实验子程序:#include "my2.h"#include "stdio.h"void my2(){int i=1;float s=1int N;printf("Please input n:\n");scanf("%d",&N);for(i,i<=n,i++)s*=i;printf("result:");printf("%f",s);}3).h头文件:#ifndef _MY2_H#define _MY2_Hint main();void my2();#endif4)makefile执行文件:zzmgo: my2.o my1.ogcc -o zzmgo my2.o my1.o my1.o: my1.c my2.hgcc -c my1.cmy2.o:my2.c my2.hgcc -c my2.cclean:rm -rf my1.o my2.o zzmgo1.多线程程序设计:#include <stdio.h>#include <stdlib.h>#include <time.h>#include "pthread.h"#define BUFFER_SIZE 16/* Circular buffer of integers. */struct prodcons {int buffer[BUFFER_SIZE];/* the actual data */pthread_mutex_t lock;/* mutex ensuring exclusive access to buffer */int readpos, writepos;/* positions for reading and writing */pthread_cond_t notempty;/* signaled when buffer is not empty */pthread_cond_t notfull;/* signaled when buffer is not full */};/*--------------------------------------------------------*//* Initialize a buffer */void init(struct prodcons * b){pthread_mutex_init(&b->lock, NULL);pthread_cond_init(&b->notempty, NULL);pthread_cond_init(&b->notfull, NULL);b->readpos = 0;b->writepos = 0;}/*--------------------------------------------------------*//* Store an integer in the buffer */void put(struct prodcons * b, int data){pthread_mutex_lock(&b->lock);/* Wait until buffer is not full */while ((b->writepos + 1) % BUFFER_SIZE == b->readpos) {printf("wait for not full\n");pthread_cond_wait(&b->notfull,&b->lock);}/* Write the data and advance write pointer */b->buffer[b->writepos] = data;b->writepos++;if (b->writepos >= BUFFER_SIZE) b->writepos = 0;/* Signal that the buffer is now not empty */pthread_cond_signal(&b->notempty);pthread_mutex_unlock(&b->lock);}/*--------------------------------------------------------*//* Read and remove an integer fromthe buffer */int get(struct prodcons * b){int data;pthread_mutex_lock(&b->lock);/* Wait until buffer is not empty */while (b->writepos == b->readpos) {printf("wait for not empty\n");pthread_cond_wait(&b->notempty,&b->lock);}/* Read the data and advance read pointer */data = b->buffer[b->readpos];b->readpos++;if (b->readpos >= BUFFER_SIZE) b->readpos = 0;/* Signal that the buffer is now not full */pthread_cond_signal(&b->notfull);pthread_mutex_unlock(&b->lock);return data;}/*--------------------------------------------------------*/#define OVER (-1)struct prodcons buffer;/*--------------------------------------------------------*/void * producer(void * data){int n;for (n = 0; n < 1000; n++) {printf(" put-->%d\n", n);put(&buffer, n);}put(&buffer, OVER);printf("producer stopped!\n");return NULL;}/*--------------------------------------------------------*/void * consumer(void * data){int d;while (1) {d = get(&buffer);if (d == OVER ) break;printf(" %d-->get\n", d);}printf("consumer stopped!\n");return NULL;}/*--------------------------------------------------------*/int main(void){pthread_t th_a, th_b;void * retval;init(&buffer);pthread_create(&th_a, NULL, producer, 0);pthread_create(&th_b, NULL, consumer, 0);/* Wait until producer and consumer finish.*/pthread_join(th_a, &retval);pthread_join(th_b, &retval);return 0;}六、实验数据分析及处理1.实验结构流程图:本实验为著名的生产者-消费者问题模型的实现,主程序中分别启动生产者线程和消费者线程。
嵌入式操作系统的多线程机制研究与实现
![嵌入式操作系统的多线程机制研究与实现](https://img.taocdn.com/s3/m/9c472b5852ea551810a687aa.png)
嵌入式操作系统的多线程机制研究与实现作者:陈雪芳来源:《电脑知识与技术》2011年第07期摘要:通过对嵌入式操作系统的多线程机制的理论进行研究与分析,提出了一种应用在嵌入式操作系统中的多线程机制实现方案。
方案以多线程机制的理论为基础,建立了多线程机制的实现模型,并以Cortex-M3内核为例,深入的分析了这种多线程机制模型的调度实现方案,以及多线程的创建,切换,延时功能函数的实现。
嵌入式操作系统的多线程机制的实现以实际应用为基础,以堆栈溢出为例,着重探讨了多线程机制在实现过程当中需要注意的安全因素。
关键词:嵌入式;操作系统;多线程;进程;Cortex-M3中图分类号:TP316文献标识码:A 文章编号:1009-3044(2011)07-1646-03Research and Implement of Multi-threads Technology Based on Embedded OSCHEN Xue-fang(Computer School, Dongguan University of Technology, Dongguan 523808, China)Abstract: A new implement of multi-threads technology in embedded operating system is introduced in this paper, which is developed from traditional theory of multi-threads technology. A model of this new implement of multi-threads is bulit up and then the schedule how to create create, switch and delay multi-threads are deeply analyzed. All these operation is implemented in Cortex-M3 core. The implement of multi-threads technology in embedded operating system is based on practical applications. And the stack overflow action is taken as an example, to show design security factor while implement multi-threads.Key words: embedded; operating system; multi-threads; process; Cortes-M3随着嵌入式技术的发展,基于对整个系统(产品)软件的安全性,可靠性,开发周期等多方面因素的考虑,嵌入式操作系统正成为嵌入式系统不可缺少的重要组成部分。
嵌入式系统开发实验二
![嵌入式系统开发实验二](https://img.taocdn.com/s3/m/16ac15f3aef8941ea76e05b0.png)
UART通讯实验学习本章实验之前,请大家仔细阅读开发板光盘\YLE2440W用户光盘(V1.6)\芯片资料文件夹下um_s3c2440a_rev10.pdf文档的第七章CLOCK & POWER MANAGEMENT,第9章I/O PORTS中GPH口设置部分,第11章UART,开发板光盘\YLE2440W用户光盘(V1.6)\使用手册文件夹下YLE2440W_V2009.pdf中关于硬件资源分配的接口说明部分以及\YLE2440W用户光盘(V1.6)\ 原理图\原理图_PDF格式文件夹下YLE2440-CORE-V1.0.pdf,了解UART与串口如何进行连接。
在学习开发板UART通信实验前,我们先了解下PC机如果通过超级终端与开发板连接进行通信。
1.超级终端的设置在Windows XP操作系统下,开始—>附件—>通讯—>超级终端。
然后出现如图1所示对话框,勾选上当选按钮请不要再问这个问题,并选择否。
图1 选择Telent程序出现如下图2所示对话框,输入区号后点击确定。
图2位置信息设置为超级终端命名一个名称(可以用户自己自行选择),并选择一个图标,如图3所示点击确定。
图3 超级终端命名出现如图4所示对话框,选择串口1,点击确定。
图4 串口选择如图5选择波特率,数据位等,注意数据流控制选择无,然后选择确定图5 串口属性设置为了以后操作方便,我们可以将已经设置好的超级终端保存起来,在超级终端菜单栏选择文件—>另存为,保存到你想要的地方以方便下次操作。
如图6所示图6 另存超级终端设置好超级终端后,使用串口线将PC机与开发板P2口连接起来,通上电源后重启开发板,就可以发现PC机和开发板能够通信了,如图7所示图7 PC机串口与开发板连接这样,PC机与开发板的连接就建立成功了。
下面我们来学习下开发板的UART通信。
2.S3C2440 UART简介UART:Universal Asynchronous Receiver/Transmitter(通用异步收发送器),用来传输串行数据,发送数据时,CPU将并行数据写入UART,UART按照一定格式在TxD线上串行发出;接收数据时,UART检测到RxD线上的信号,将串行收集放到缓冲区中,CPU即可读取UART获得的这些数据。
嵌入式Linux多线程编程实验
![嵌入式Linux多线程编程实验](https://img.taocdn.com/s3/m/c194939bb1717fd5360cba1aa8114431b90d8ef4.png)
实验二、嵌入式Linux多线程编程实验一、实验目的1. 熟悉线程的定义、创建及应用方法,掌握编译源代码时引入线程库的方法。
2. 掌握如何利用信号量完成线程间的同步与互斥。
3. 熟悉Makefile工作原理,掌握编写Makefile的编写方法。
二、实验基本要求1. 掌握熟悉线程的定义及操作方法。
2. 利用信号量的PV操作完成完成以下单个生产者和单个消费者模型的代码。
3. 编写在Ubuntu中编译执行的makefile文件,然后在Ubuntu中执行。
4. 编写在实验箱中编译执行的makefile文件,然后在实验箱中执行。
注意Makefile编写规范缩进应使用制表键即Tab键。
三、实验原理1.Linux线程的定义线程(thread)是在共享内存空间中并发的多道执行路径,它们共享一个进程的资源,如文件描述和信号处理。
在两个普通进程(非线程)间进行切换时,内核准备从一个进程的上下文切换到另一个进程的上下文要花费很大的开销。
这里上下文切换的主要任务是保存老进程CPU状态并加载新进程的保存状态,用新进程的内存映像替换进程的内存映像。
线程允许你的进程在几个正在运行的任务之间进行切换,而不必执行前面提到的完整的上下文。
另外本文介绍的线程是针对POSIX线程,也就是pthread。
也因为Linux对它的支持最好。
相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
在串行程序基础上引入线程和进程是为了提高程序的并发度,从而提高程序运行效率和响应时间。
也可以将线程和轻量级进程(LWP)视为等同的,但其实在不同的系统/实现中有不同的解释,LWP更恰当的解释为一个虚拟CPU或内核的线程。
它可以帮助用户态线程实现一些特殊的功能。
Pthread是一种标准化模型,它用来把一个程序分成一组能够同时执行的任务。
2. 什么场合会使用Pthread即线程(1) 在返回前阻塞的I/O任务能够使用一个线程处理I/O,同时继续执行其他处理任务。
湖北汽院嵌入式系统开发实验
![湖北汽院嵌入式系统开发实验](https://img.taocdn.com/s3/m/0fb2422edd36a32d73758118.png)
实验二嵌入式 Linux 多线程通信实验程(thread)是在共享内存空间中并发的多道执行路径,它们共享一个进程的资源,如文件描述和信号处理。
P(S):①将信号量S 的值减1,即S=S-1;②如果S≥0,则该进程继续执行;否则该进程状态置为阻塞状态,进程PCB 排入信号量PCB 队列末尾,放弃CPU,等待V 操作的执行。
V(S):1 将信号量S 的值加1,即S=S+1;2 如果S≤0,释放信号量队列中第一个PCB 所对应的进程,将进程状态由阻塞态改为就绪态。
执行V 操作的进程继续执行。
#include <stdio.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>#define MAXSIZE 10int stack[MAXSIZE];int size=50;int front=-1,rear=0;sem_t avail,full; //avail 表示可用的空缓冲区,full 表示已存放产品的缓冲区//生产者pthread_t provider,customer,end;void provider_fun(void) //full 表示已存放产品的缓冲区{int i=1;sleep(5);while(i<=size) //生产50 个产品,需要放入到MAXSIZE 个缓冲区中{sem_wait(&avail); //avail 信号量P 操作,表示将可用的空缓冲区个数减1stack[rear]=i;printf("produce the %d product\n",stack[rear]);rear=(rear+1)%MAXSIZE;i++;sleep(1);sem_post(&full); //full 信号量V 操作,表示将存放产品的缓冲区个数加1}pthread_exit(NULL);}//消费者void customer_fun(void){int i=1;while(i<=size){sem_wait(&full); //fulll 信号量P 操作,表示将存放产品的缓冲区个数减1front=(front+1)%MAXSIZE;printf("\t consume the%d product\n",stack[front]);stack[front]=0;sleep(2);sem_post(&avail); //avail 信号量V 操作,表示将可用的空缓冲区个数加1i++;}pthread_exit(NULL);}void end_fun(void){char ch;scanf("%c",&ch);pthread_cancel(provider);pthread_cancel(customer);dpthread_exit(NULL);printf("exit!\n");}void main(){pthread_t provider,customer; //定义生产者线程对象和消费者线程对象sem_init(&avail,0,MAXSIZE); //将avail 信号量初始化为MAXSIZEsem_init(&full,0,0); //将full 信号量初始化为0pthread_create(&provider, NULL, (void *)provider_fun, NULL); // 创建生产者线程pthread_create(&customer, NULL, (void *)customer_fun, NULL);// 消费者线程pthread_create(&end, NULL, (void *)end_fun, NULL);pthread_join(provider,NULL);pthread_join(customer,NULL);pthread_join(end,NULL);sem_destroy(&avail);sem_destroy(&full);}实验三、嵌入式 Linux 网络通信实验3、TCP套接字通信步骤服务器端:(1)调用socket()创建套接字,然后初始化struct sockaddr_in结构体。
多线程编程实验报告
![多线程编程实验报告](https://img.taocdn.com/s3/m/a816fe2c03768e9951e79b89680203d8ce2f6a2b.png)
一、实验目的1. 理解多线程编程的基本概念和原理。
2. 掌握多线程的创建、同步、通信和调度等关键技术。
3. 通过实验加深对多线程编程的理解,提高编程能力。
二、实验环境硬件:PC机软件:VMware虚拟机、Linux系统、C/C++编译器三、实验内容1. 多线程创建与运行2. 线程同步与互斥3. 线程通信与协作4. 线程调度与优先级5. 生产者-消费者问题四、实验步骤1. 多线程创建与运行(1)创建线程:使用pthread_create函数创建线程,指定线程的入口函数、参数、线程属性等。
(2)线程运行:编写线程入口函数,实现线程需要执行的任务。
(3)线程结束:在线程入口函数中执行任务后,使用pthread_exit函数结束线程。
2. 线程同步与互斥(1)互斥锁:使用pthread_mutex_lock和pthread_mutex_unlock函数实现互斥锁,保证同一时刻只有一个线程访问共享资源。
(2)条件变量:使用pthread_cond_wait和pthread_cond_signal函数实现条件变量,实现线程间的同步与协作。
(3)读写锁:使用pthread_rwlock_rdlock和pthread_rwlock_wrlock函数实现读写锁,允许多个线程同时读取共享资源,但只有一个线程可以写入。
3. 线程通信与协作(1)线程间通信:使用pthread_cond_signal、pthread_cond_broadcast、pthread_barrier_wait等函数实现线程间的通信。
(2)线程协作:使用pthread_barrier_init、pthread_barrier_wait函数实现线程间的协作,确保所有线程到达某个点后再继续执行。
4. 线程调度与优先级(1)线程调度:了解操作系统的线程调度算法,如时间片轮转、优先级调度等。
(2)线程优先级:使用pthread_setschedparam函数设置线程的调度策略和优先级。
嵌入式操作系统—多线程-实验报告(11-多线程编程)
![嵌入式操作系统—多线程-实验报告(11-多线程编程)](https://img.taocdn.com/s3/m/6c95511908a1284ac9504325.png)
程序实验二:11-多线程编程实验专业班级实验日期姓名学号实验一(p284:11-thread.c)1、软件功能描述创建3个线程,为了更好的描述线程之间的并行执行,让3个线程重用同一个执行函数。
每个线程都有5次循环,每次循环之间会随机等待1-10s的时间。
2、程序流程设计3.部分程序代码注释(关键函数或代码)res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);创建线程res = pthread_join(thread[no], &thrd_ret);等待线程结束4.编译、运行方法及结果(抓屏)5.结果分析每个线程的运行和结束在宏观上是独立与并行的。
实验二(p287: 11-thread_mutex.c)1、软件功能描述增加线程互斥锁功能,实现原本独立与无序的多个线程能够按序执行。
2、程序流程设计3.部分程序代码注释(关键函数或代码)res = pthread_mutex_lock(&mutex);互斥锁上锁pthread_create(&thread[no], NULL, thrd_func, (void*)no);创建线程pthread_mutex_unlock(&mutex);互斥锁解锁4.编译、运行方法及结果(抓屏)5.结果分析通过增加互斥锁之后,在同一时刻只能有一个线程能够对共享资源进行操作。
其他线程想要上锁已经被上锁的互斥锁,则线程就会被挂起。
因此线程将按照创建的顺序执行。
实验三(P291:11-thread_sem.c)1、软件功能描述利用信号量同步机制实现3个线程之间的有序执行,只是执行顺序跟创建线程相反。
2、程序流程设计3.部分程序代码注释(关键函数或代码)sem_wait(&sem[thrd_num]);进行P操作res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);创建新线程sem_post(&sem[THREAD_NUMBER - 1]);对最后创建的线程信号量进行V操作sem_destroy(&sem[no]);4.编译、运行方法及结果(抓屏)5.结果分析代码有问题,运行之后首先执行的是Thread 2然后就死锁了,我觉得线程解锁应该放在线程执行代码里面。
电子科大 第7章 嵌入式Linux软件设计-多线程
![电子科大 第7章 嵌入式Linux软件设计-多线程](https://img.taocdn.com/s3/m/c3528237b90d6c85ec3ac64f.png)
线程理论基础
编译
候要加上-lpthread
第7章 嵌入式Linux软件设计
因为pthread的库不是Linux系统的库,所以在进行编译的时
#gcc filename -lpthread
10
线程理论基础
终止线程 都会终止。线程的正常退出方式有: 线程从启动例程中返回; 线程可以被另一个进程终止; 线程自己调用pthread_exit函数。
void pthread_cleanup_push(void(*rtn)(void *),void *arg) 功能:将清除函数压入清除栈 rtn:清除函数; arg:清除函数的参数。
18
线程理论基础
清除
#include <pthread.h>
第7章 嵌入式Linux软件设计
void pthread_cleanup_pop(int execute) 功能:将清除函数弹出清除栈 execute执行到pthread_cleanup_pop()时是否在弹出清理 函数的同时执行该函数,非0:执行;0:不执行。
8
线程理论基础
创建线程
#include <pthread.h>
第7章 嵌入式Linux软件设计
Int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, void *(*start_rtn)(void),void *arg) tidp:线程id attr:线程属性(通常为空) start_rtn:线程要执行的函数 arg:start_rtn的参数
19
5
线程理论基础
使用多线程的理由
如下优点:
第7章 嵌入式Linux软件设计
实验2_Linux开发环境搭建及多线程应用程序设计
![实验2_Linux开发环境搭建及多线程应用程序设计](https://img.taocdn.com/s3/m/374d765de518964bcf847cba.png)
嵌入式系统设计实验二Linux开发环境搭建与多线程应用程序设计姓名:专业:嵌入式系统设计学号:日期:目录第一章Linux开发环境搭建 (3)1.1安装配置minicom (3)1.2安装arm-linux-gcc交叉编译器 (3)1.3安装配置nfs (5)第二章多线程应用程序设计 (8)2.1 多线程应用程序设计 (8)2.2交叉编译 (11)第一章Linux开发环境搭建1.1安装配置minicom安装minicom可分为两步:(1)更新apt-get命令为:apt-get update(2)下载安装minicom命令为:apt-get install minicom安装完成页面如下图所示:配置minicom的串口参数如下图所示:串口设备名改为ttyS0串口波特率为115200,8位数据位,1位停止位。
硬件控制流位关闭。
1.2安装arm-linux-gcc交叉编译器安装arm-linux-gcc。
在实验过程中,使用arm-linux-gcc 3.4.1版本的编译器。
安装可分为三步:(1)解压并安装解压并安装命令:tar –xjvf arm-linux-gcc-3.4.1.tar.bz2 –C /armtools(2)配置编译器路径在文件/etc/profile末尾添加export PATH=$PATH:/armtools/usr/local/arm/ 3.4.1/bin修改保存后输入命令:source /etc/profile 应用路径(3)查询是否安装成功可以输入arm-linux-gcc –v查询版本号如下图所示:1.3安装配置nfs安装配置nfs的目的是与开发板通过网线进行通信,并烧写程序。
安装配置可分为四步:(1)安装nfs服务下载安装nfs服务命令为:apt-get install nfs-kernel-server,成功后如下图所示:(2)配置网段在宿主机修改共享文件夹配置文件:(3)重启nfs服务重启命令为:/etc/init.d/portmap restart/etc/init.d/nfs-kernel-server restart(4)挂载设备第一步打开minicom,启动开发板,观察串口输出。
嵌入式系统技术实验报告
![嵌入式系统技术实验报告](https://img.taocdn.com/s3/m/f4738d6c0b1c59eef8c7b46b.png)
南京理工大学嵌入式系统技术实验报告作者: 学号:学院(系):班级:指导老师:孙瑜实验日期: 2014年11月实验一:熟悉Linux 开发环境一、实验目的熟悉Linux开发环境,学会基于S3C2410的Linux开发环境的配置和使用。
使用Linux的armv4l-unknown-linux-gcc编译,使用基于NFS方式的下载调试,了解嵌入式开发的基本过程。
二、实验仪器硬件:UP-NETARM2410-S嵌入式实验平台、PC机。
软件:PC机操作系统REDHAT LINUX 9.0+MINICOM+ARM-LINUX开发环境三、实验内容本次实验使用Redhat Linux 9.0操作系统环境,安装ARM-Linux的开发库及编译器。
创建一个新目录,并在其中编写hello文件。
学习在Linux下的编程和编译过程,以及ARM开发板的使用和开发环境的设置。
下载已经编译好的文件到目标开发板上运行。
四、实验步骤1、建立工作目录[root@zxt smile]# mkdir hello[root@zxt smile]# cd hello2、编写程序源代码实际的hello.c源代码较简单,如下:#include <stdio.h>void main(void){printf(“hello world \n”);}用下面的命令来编写“hello.c”的源代码,进入hello目录使用vi命令来编辑代码:[root@zxt hello]# vi hello.c按“i”或者“a”进入编辑模式,录入上面的代码,完成后按Esc键进入命令状态,再用命令“:wq ”,保存并退出。
这样在当前目录下建立了一个名为“hello.c”的文件。
3、编译链接要使上面的“hello.c”程序能够运行,将其经过编译和连接,生成可执行文件。
输入 gcc hello.c -o hello 进行编译,再输入 ./hello 运行程序,观察结果1。
多线程实验报告
![多线程实验报告](https://img.taocdn.com/s3/m/4ec1667d5627a5e9856a561252d380eb6294239e.png)
多线程实验报告多线程实验报告引言:多线程是计算机科学中的一个重要概念,它允许程序同时执行多个任务,提高了计算机的效率和响应能力。
本实验旨在探索多线程的原理和应用,通过编写并运行多线程程序,研究多线程在不同场景下的表现和效果。
一、实验目的本实验的目的是通过编写多线程程序,深入了解多线程的工作原理和应用场景,掌握多线程编程的技巧和方法。
二、实验环境本实验使用Java语言进行多线程编程,运行环境为Windows操作系统。
三、实验过程1. 线程的创建与启动在Java中,创建一个线程可以通过继承Thread类或实现Runnable接口来实现。
本实验选择实现Runnable接口的方式来创建线程。
```javapublic class MyThread implements Runnable {public void run() {// 线程的执行逻辑}}public class Main {public static void main(String[] args) {Thread thread = new Thread(new MyThread());thread.start();}}```通过上述代码,我们创建了一个名为MyThread的线程类,并在Main类的main方法中创建并启动了一个线程。
2. 线程的同步与互斥在多线程编程中,线程的同步与互斥非常重要。
为了保证线程的安全性,我们需要使用锁机制来控制多个线程对共享资源的访问。
```javapublic class MyThread implements Runnable {private static int count = 0;private static Object lock = new Object();public void run() {synchronized (lock) {for (int i = 0; i < 100; i++) {count++;}}}}public class Main {public static void main(String[] args) {Thread thread1 = new Thread(new MyThread());Thread thread2 = new Thread(new MyThread());thread1.start();thread2.start();}}```上述代码中,我们使用了一个静态对象lock作为锁,通过synchronized关键字来实现对共享资源count的互斥访问。
多线程基础实验报告
![多线程基础实验报告](https://img.taocdn.com/s3/m/f8fb238c250c844769eae009581b6bd97f19bcac.png)
一、实验目的1. 理解多线程的概念及其在程序设计中的应用。
2. 掌握在Java中创建和使用线程的基本方法。
3. 学习线程的同步和互斥机制,理解死锁、线程安全等概念。
4. 了解线程的生命周期及其状态转换。
二、实验环境- 操作系统:Windows 10- 开发工具:Eclipse IDE- 编程语言:Java三、实验内容本次实验主要围绕以下内容展开:1. 线程的基本操作:创建线程、启动线程、线程的执行、线程的终止。
2. 线程的同步与互斥:使用synchronized关键字实现线程同步,防止数据竞态。
3. 线程的通信:使用wait()、notify()、notifyAll()方法实现线程间的通信。
4. 线程池:使用ExecutorService创建线程池,提高线程复用率。
5. 线程的生命周期:观察线程的状态转换,理解线程的创建、运行、阻塞、终止等过程。
四、实验步骤1. 创建线程:- 通过继承Thread类创建线程,并重写run()方法。
- 通过实现Runnable接口创建线程,将任务封装在Runnable对象中。
- 使用匿名内部类创建线程。
2. 线程的同步与互斥:- 使用synchronized关键字对共享资源进行加锁,保证同一时间只有一个线程可以访问。
- 使用ReentrantLock类实现线程同步,提供更丰富的锁操作。
3. 线程的通信:- 使用wait()、notify()、notifyAll()方法实现线程间的通信,解决生产者-消费者问题。
4. 线程池:- 使用ExecutorService创建线程池,提高线程复用率。
- 使用Future接口获取线程执行结果。
5. 线程的生命周期:- 使用Thread类的方法观察线程的状态,如isAlive()、getState()等。
五、实验结果与分析1. 创建线程:- 通过继承Thread类、实现Runnable接口和匿名内部类成功创建了线程,并观察到线程的执行。
嵌入式系统实验报告(二)
![嵌入式系统实验报告(二)](https://img.taocdn.com/s3/m/3893af1ebb68a98271fefa81.png)
嵌入式实验报告实验十九键盘驱动实验一.实验内容主要完成目标板键盘的驱动,当按下目标板上的键盘时,超级终端会显示按键的键值。
二.作业基于LED点阵和数码管显示,通过设计编写程序,完成键盘加减乘除运算。
并在数码管上显示所键入的数字功能。
在终端上显示键入内容和计算结果。
三.程序代码#include<stdio.h>#include<string.h>#include<stdlib.h>#include<fcntl.h>#include<unistd.h>#include<math.h>#define DEVICE_NAME “/dev/keyboard”int main(void){intfd;int ret;unsigned char buf[1];inti,f,j;double x;int a[2]={0};charpre_scancode=0xff;fd=open(DEVICE_NAME,O_RDWR);if(fd==-1)printf(“open device %s error\n”,DEVICE_NAME);else{buf[0]=0xff;i=0;f=0;while(1){read(fd,buf,1);if(buf[0]!=pre_scancode) //判断是否放开按键if(buf[0]!=0xff){ //判断是否键入pre_scancode=buf[0];usleep(50000);switch(buf[0]){case 0x12:{ //按下enterswitch(f){ //判断运算符case1:{j=i;i=(i+1)%2;x=a[i]+a[j];printf(“%d+%d=%d”,a[i],a[j],x);break;}//加法case2:{j=i;i=(i+1)%2;x=a[i]-a[j];printf(“%d-%d=%d”,a[i],a[j],x);break;}//减法case3:{j=i;i=(i+1)%2;x=a[i]*a[j];printf(“%d*%d=%d”,a[i],a[j],x);break;}//乘法case4:{j=i;i=(i+1)%2;x=a[i]/a[j];printf(“%d/%d=%d”,a[i],a[j],x);break;}//除法defauit:}f=0;break;}case 0x13:{f=1;i=(i+1)%2;break;} //键入运算符case 0x14:{f=2;i=(i+1)%2;break;}case 0x15:{f=3;i=(i+1)%2;break;}case 0x16:{f=4;i=(i+1)%2;break;}default:a[i]=buf[0]; //存入数据}}}ret=close(fd);}return 0;}本测试程序完成了键盘的加减乘除运算,可以在终端显示键入的内容和计算结果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
注意实验二是在实验一的基础上完成其内容,具体环境配置见实验一目录实验二多线程应用程序设计 (2)2.1实验目的 (2)2.2、实验内容 (2)2.3、预备知识 (2)2.4、实验设备及工具 (2)2.5、实验原理及代码分析 (3)2.6、实验步骤 (11)2.7、思考题 (13)实验二多线程应用程序设计2.1实验目的⏹了解多线程程序设计的基本原理。
⏹学习pthread库函数的使用。
2.2、实验内容⏹读懂pthread.c的源代码,熟悉几个重要的pthread库函数的使用。
掌握共享锁和信号量的使用方法。
⏹进入/root/share/exp/basic/02_pthread目录,运行make 产生pthread程序,使用NFS方式连接开发主机进行运行实验。
2.3、预备知识⏹有C语言基础⏹掌握在Linux下常用编辑器的使用⏹掌握Makefile 的编写和使用⏹掌握Linux下的程序编译与交叉编译过程2.4、实验设备及工具⏹硬件:UP-TECH S2410/P270 DVP嵌入式实验平台,PC机Pentium 500以上, 硬盘40G以上,内存大于128M。
⏹软件:PC机操作系统REDHAT LINUX 9.0 +MINICOM + ARM-LINUX开发环境2.5、实验原理及代码分析1.多线程程序的优缺点⏹多线程程序作为一种多任务、并发的工作方式,有以下的优点:⏹1)提高应用程序响应。
这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。
⏹2)使多CPU系统更加有效。
操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。
⏹3)改善程序结构。
一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
⏹Libc中的pthread库提供了大量的API函数,为用户编写应用程序提供支持。
2.实验源代码与结构流程图⏹本实验为著名的生产者-消费者问题模型的实现,主程序中分别启动生产者线程和消费者线程。
生产者线程不断顺序地将0到1000的数字写入共享的循环缓冲区,同时消费者线程不断地从共享的循环缓冲区读取数据。
流程图如图2.2.1所示:图2.1生产者-消费者实验源代码结构流程图本实验具体代码如下:3.主要函数分析:下面我们来看一下,生产者写入缓冲区和消费者从缓冲区读数的具体流程,生产者首先要获得互斥锁,并且判断写指针+1后是否等于读指针,如果相等则进入等待状态,等候条件变量notfull;如果不等则向缓冲区中写一个整数,并且设置条件变量为notempty,最后释放互斥锁。
消费者线程与生产者线程类似,这里就不再过多介绍了。
流程图如下:s图2.2 生产消费流程图生产者写入共享的循环缓冲区函数PUT消费者读取共享的循环缓冲区函数GET4.主要的多线程API⏹在本程序的代码中大量的使用了线程函数,如pthread_cond_signal、pthread_mutex_init、pthread_mutex_lock等等,这些函数的作用是什么,在哪里定义的,我们将在下面的内容中为大家做一个简单的介绍,并且为其中比较重要的函数做一些详细的说明。
⏹PTHREAD库中还有大量的API函数,用户可以参考其他相关书籍。
下面我们对几个比较重要的函数做一下详细的说明:⏹pthread_create线程创建函数⏹线程创建函数第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数。
这里,我们的函数thread不需要参数,所以最后一个参数设为空指针。
第二个参数我们也设为空指针,这样将生成默认属性的线程。
当创建线程成功时,函数返回0,若不为0则说明创建线程失败,常见的错误返回代码为EAGAIN 和EINVAL。
前者表示系统限制创建新的线程,例如线程数目过多了;后者表示第二个参数代表的线程属性值非法。
创建线程成功后,新创建的线程则运行参数三和参数四确定的函数,原来的线程则继续运行下一行代码。
⏹第一个参数为被等待的线程标识符,第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。
pthread_exit函数⏹一个线程的结束有两种途径,一种是象我们上面的例子一样,函数结束了,调用它的线程也就结束了;另一种方式是通过函数pthread_exit来实现。
它的函数原型为:⏹唯一的参数是函数的返回代码,只要pthread_join中的第二个参数thread_return不是NULL,这个值将被传递给thread_return。
最后要说明的是,一个线程不能被多个线程等待,否则第一个接收到信号的线程成功返回,其余调用pthread_join的线程则返回错误代码ESRCH。
⏹下面我们来介绍有关条件变量的内容。
使用互斥锁来可实现线程间数据的共享和通信,互斥锁一个明显的缺点是它只有两种状态:锁定和非锁定。
而条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用。
使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。
一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。
这些线程将重新锁定互斥锁并重新测试条件是否满足。
一般说来,条件变量被用来进行线线程间的同步。
pthread_cond_init函数⏹条件变量的结构为pthread_cond_t,函数pthread_cond_init()被用来初始化一个条件变量。
它的原型为:⏹其中cond是一个指向结构pthread_cond_t的指针,cond_attr是一个指向结构pthread_condattr_t的指针。
结构pthread_condattr_t是条件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用。
注意初始化条件变量只有未被使用时才能重新初始化或被释放。
释放一个条件变量的函数为pthread_cond_ destroy(pthread_cond_t cond)。
线程解开mutex指向的锁并被条件变量cond阻塞。
线程可以被函数pthread_cond_signal和函数pthread_cond_broadcast唤醒,但是要注意的是,条件变量只是起阻塞和唤醒线程的作用,具体的判断条件还需用户给出,例如一个变量是否为0等等,这一点我们从后面的例子中可以看到。
线程被唤醒后,它将重新检查判断条件是否满足,如果还不满足,一般说来线程应该仍阻塞在这里,被等待被下一次唤醒。
这个过程一般用while 语句实现。
pthread_cond_timedwait函数⏹另一个用来阻塞线程的函数是pthread_cond_timedwait(),它的原型为:⏹它比函数pthread_cond_wait()多了一个时间参数,经历abstime段时间后,即使条件变量不满足,阻塞也被解除。
⏹它用来释放被阻塞在条件变量cond上的一个线程。
多个线程阻塞在此条件变量上时,哪一个线程被唤醒是由线程的调度策略所决定的。
要注意的是,必须用保护条件变量的互斥锁来保护这个函数,否则条件满足信号又可能在测试条件和调用pthread_cond_wait函数之间被发出,从而造成无限制的等待。
2.6、实验步骤1、阅读源代及编译应用程序进入/root/share/exp/basic/02_pthread目录,使用vi编辑器或其他编辑器阅读理解源代码。
运行make产生pthread可执行文件。
图2.3在linux下make多线程2、下切换到minicom终端窗口,先像实验一一样,把串口、网线、电源线接好,配置好实验箱的IP地址,然后使用NFS mount宿主机(虚拟linux)的/root/share 到目标板(实验箱)/host目录。
具体命令见图片中的命令,注意IP地址根据自己的情况进行相应的修改:图2.4配置实验箱IP地址并mount 宿主机linux的/root/share到目标板(实验箱)/host目录⏹进入/host/exp/basic/pthread目录,运行pthread,观察运行结果的正确性。
运行程序最后一部分结果如下:⏹图2.5进入/host/exp/basic/pthread目录运行pthread⏹图2.6运行结果画面2.7、思考题⏹1.加入一个新的线程用于处理键盘的输入,并在按键为ESC时终止所有线程。
⏹2.线程的优先级的控制。