程序设计实践6w 线程、时间函数和设计问题
java多线程程序设计实验总结

java多线程程序设计实验总结一、实验目的本次实验旨在通过编写Java多线程程序,掌握多线程编程的基本概念和技能,理解多线程程序的运行原理,提高对Java语言的熟练度。
二、实验内容本次实验分为三个部分:创建线程、线程同步和死锁。
2.1 创建线程创建线程有两种方式:继承Thread类和实现Runnable接口。
继承Thread类需要重写run方法,在run方法中编写线程执行的代码;实现Runnable接口需要实现run方法,并将其作为参数传入Thread类的构造函数中。
在创建多个线程时,可以使用同一个Runnable对象或者不同的Runnable对象。
2.2 线程同步当多个线程同时访问共享资源时,可能会出现数据不一致等问题。
为了避免这种情况,需要使用同步机制来保证各个线程之间的协调运行。
常见的同步机制包括synchronized关键字和Lock接口。
synchronized关键字可以用来修饰方法或代码块,在执行该方法或代码块时,其他所有试图访问该方法或代码块的线程都必须等待当前执行完成后才能继续执行。
Lock接口提供了更加灵活和高级的锁机制,可以支持更多种类型的锁,如读写锁、可重入锁等。
2.3 死锁死锁是指两个或多个线程在互相等待对方释放资源的情况下,都无法继续执行的现象。
死锁的发生通常由于程序设计不当或者资源分配不合理所导致。
为避免死锁的发生,可以采取以下措施:避免嵌套锁、按照固定顺序获取锁、避免长时间占用资源等。
三、实验过程本次实验我编写了多个Java多线程程序,包括创建线程、线程同步和死锁。
其中,创建线程部分我使用了继承Thread类和实现Runnable 接口两种方式来创建线程,并测试了多个线程之间的并行执行情况;在线程同步部分,我使用synchronized关键字和Lock接口来保证共享资源的访问安全,并测试了多个线程同时访问共享资源时是否会出现数据不一致等问题;在死锁部分,我编写了一个简单的死锁程序,并通过调整程序代码来避免死锁的发生。
线程实例实验报告总结

一、实验目的本次实验旨在通过实例操作,深入了解线程的概念、创建、同步与通信机制,以及线程在实际编程中的应用。
通过实验,提高对线程的理解和运用能力,为以后开发多线程程序打下坚实基础。
二、实验环境1. 操作系统:Windows 102. 开发工具:Visual Studio 20193. 编程语言:C#三、实验内容1. 线程的基本概念线程是程序执行的最小单位,是操作系统进行资源分配和调度的基本单位。
线程具有以下特点:(1)线程是轻量级的,创建、销毁线程的开销较小。
(2)线程共享进程的资源,如内存、文件等。
(3)线程之间可以并发执行。
2. 线程的创建在C#中,可以使用以下方式创建线程:(1)使用Thread类```csharpThread thread = new Thread(new ThreadStart(MethodName));thread.Start();```(2)使用lambda表达式```csharpThread thread = new Thread(() => MethodName());thread.Start();```(3)使用匿名方法```csharpThread thread = new Thread(delegate () { MethodName(); });thread.Start();```3. 线程的同步线程同步是指多个线程在执行过程中,为了防止资源冲突而采取的协调机制。
C#提供了以下同步机制:(1)互斥锁(Mutex)```csharpMutex mutex = new Mutex();mutex.WaitOne();// 线程同步代码mutex.ReleaseMutex();```(2)信号量(Semaphore)```csharpSemaphore semaphore = new Semaphore(1, 1);semaphore.WaitOne();// 线程同步代码semaphore.Release();```(3)读写锁(ReaderWriterLock)```csharpReaderWriterLock rwlock = new ReaderWriterLock();rwlock.AcquireReaderLock();// 读取操作rwlock.ReleaseReaderLock();```4. 线程的通信线程通信是指线程之间传递消息、共享数据的过程。
最全多线程经典面试题和答案

最全多线程经典⾯试题和答案Java实现线程有哪⼏种⽅式?1、继承Thread类实现多线程2、实现Runnable接⼝⽅式实现多线程3、使⽤ExecutorService、Callable、Future实现有返回结果的多线程多线程同步有哪⼏种⽅法?Synchronized关键字,Lock锁实现,分布式锁等。
Runnable和Thread⽤哪个好?Java不⽀持类的多重继承,但允许你实现多个接⼝。
所以如果你要继承其他类,也为了减少类之间的耦合性,Runnable会更好。
Java中notify和notifyAll有什么区别?notify()⽅法不能唤醒某个具体的线程,所以只有⼀个线程在等待的时候它才有⽤武之地。
⽽notifyAll()唤醒所有线程并允许他们争夺锁确保了⾄少有⼀个线程能继续运⾏。
为什么wait/notify/notifyAll这些⽅法不在thread类⾥⾯?这是个设计相关的问题,它考察的是⾯试者对现有系统和⼀些普遍存在但看起来不合理的事物的看法。
回答这些问题的时候,你要说明为什么把这些⽅法放在Object类⾥是有意义的,还有不把它放在Thread类⾥的原因。
⼀个很明显的原因是JAVA提供的锁是对象级的⽽不是线程级的,每个对象都有锁,通过线程获得。
如果线程需要等待某些锁那么调⽤对象中的wait()⽅法就有意义了。
如果wait()⽅法定义在Thread类中,线程正在等待的是哪个锁就不明显了。
简单的说,由于wait,notify和notifyAll都是锁级别的操作,所以把他们定义在Object类中因为锁属于对象。
为什么wait和notify⽅法要在同步块中调⽤?主要是因为Java API强制要求这样做,如果你不这么做,你的代码会抛出IllegalMonitorStateException异常。
还有⼀个原因是为了避免wait 和notify之间产⽣竞态条件。
什么是死锁?如何避免死锁?死锁就是两个线程相互等待对⽅释放对象锁。
java多线程练习题

java多线程练习题在Java编程中,多线程是一个非常重要的概念,它允许程序同时执行多个任务,提高程序的效率和响应性。
以下是一些Java多线程的练习题,可以帮助你更好地理解和掌握多线程的概念和应用。
# 练习题1:线程的创建和启动编写一个Java程序,创建一个继承自Thread类的子类,并重写run 方法。
然后创建该子类的实例,并启动线程。
```javaclass MyThread extends Thread {public void run() {System.out.println("线程启动了!");}}public class Main {public static void main(String[] args) {MyThread thread = new MyThread();thread.start();}}```# 练习题2:线程的同步编写一个Java程序,模拟两个线程交替打印1到10的数字。
使用同步方法或同步代码块来保证线程安全。
```javaclass Counter {private int count = 1;public synchronized void increment() {System.out.println(Thread.currentThread().getName() + "打印了:" + count);count++;}}public class Main {public static void main(String[] args) {Counter counter = new Counter();Thread thread1 = new Thread(() -> {for (int i = 0; i < 5; i++) {counter.increment();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 5; i++) {counter.increment();}});thread1.start();thread2.start();}}```# 练习题3:使用wait和notify编写一个Java程序,模拟生产者和消费者问题。
多线程编程的常见问题和解决方法

多线程编程的常见问题和解决方法多线程编程是同时运行多个线程的编程模型,可以提高程序的并发性和响应性。
然而,多线程编程也会带来一些常见问题,如竞态条件、死锁、活锁、饥饿等。
下面是一些常见的问题和解决方法。
1.竞态条件竞态条件是指多个线程对共享资源进行访问和修改时的不确定性结果。
解决竞态条件的方法有:-使用互斥锁(mutex):通过确保一次只有一个线程能够访问共享资源,来避免竞态条件。
-使用信号量(semaphore):通过限制同时访问共享资源的线程数量来避免竞态条件。
-使用条件变量(condition variable):通过让线程等待某个条件满足,再进行访问共享资源,来避免竞态条件。
2.死锁死锁是指多个线程互相等待对方释放资源,导致系统无法继续执行的状态。
解决死锁的方法有:-避免使用多个锁:尽可能减少锁的数量,或者使用更高级的同步机制如读写锁(read-write lock)。
-破坏循环等待条件:对资源进行排序,按序请求资源,避免循环等待。
-使用超时机制:在一定时间内等待资源,如果超时则丢弃请求,避免无限等待。
3.活锁活锁是指多个线程在不停地改变自己的状态,但无法向前推进。
解决活锁的方法有:-引入随机性:当多个线程同时请求资源时,引入随机性来打破死锁的循环。
-重试策略:如果发生活锁,暂停一段时间后重新尝试执行操作。
4.饥饿饥饿是指某个线程由于优先级或其他原因无法获得资源,导致无法继续执行。
解决饥饿的方法有:-使用公平锁:确保每个线程获得资源的机会是公平的,避免某个线程一直无法获得资源。
-调整线程优先级:提高饥饿线程的优先级,使其有机会获得资源。
5.数据竞争数据竞争是指多个线程同时对共享数据进行读写操作,导致不确定的结果。
解决数据竞争的方法有:-使用互斥锁:通过确保一次只有一个线程能够访问共享数据,来避免数据竞争。
-使用原子操作:使用原子操作来保证共享数据的原子性,避免数据竞争。
6.上下文切换开销多线程编程会引入上下文切换开销,导致性能下降。
创建线程的实验报告

一、实验目的1. 理解线程的概念和作用。
2. 掌握在Java中创建线程的方法。
3. 学习线程的生命周期和线程同步。
4. 熟悉线程的调度和同步机制。
二、实验环境1. 操作系统:Windows 102. 开发工具:IntelliJ IDEA3. 编程语言:Java三、实验内容1. 创建线程2. 线程生命周期3. 线程同步4. 线程调度四、实验步骤1. 创建线程(1)继承Thread类创建线程```javapublic class MyThread extends Thread { @Overridepublic void run() {// 线程要执行的任务System.out.println("子线程:" + Thread.currentThread().getName());}}```(2)实现Runnable接口创建线程```javapublic class MyRunnable implements Runnable {@Overridepublic void run() {// 线程要执行的任务System.out.println("子线程:" +Thread.currentThread().getName());}}```2. 线程生命周期线程生命周期包括以下五个状态:(1)新建(New):线程对象被创建后,处于此状态。
(2)就绪(Runnable):线程对象被创建后,调用start()方法,线程进入就绪状态。
(3)运行(Running):线程被调度到CPU上执行,处于运行状态。
(4)阻塞(Blocked):线程因为某些原因无法执行,进入阻塞状态。
(5)终止(Terminated):线程执行完毕或被强制终止,处于终止状态。
以下代码演示了线程的生命周期:```javapublic class LifeCycleDemo {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());System.out.println("线程状态:" + thread.getState());thread.start();System.out.println("线程状态:" + thread.getState());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程状态:" + thread.getState());}}```3. 线程同步线程同步是为了避免多个线程同时访问共享资源时出现冲突。
线程和实例-概述说明以及解释

线程和实例-概述说明以及解释1.引言1.1 概述引言部分是文章的开篇,通过引言部分我们可以了解到整篇文章的大致内容和目的。
在本篇文章中,我们将深入探讨线程和实例的概念,特点,应用以及它们之间的关系。
线程是计算机科学中一个非常重要的概念,它可以使程序在同一时间内执行多个任务,提高程序的效率和性能。
而实例则是面向对象编程中的一个重要概念,它可以帮助我们更好地组织和管理程序的数据和行为。
通过本文的阐述,读者将能够更深入地了解线程和实例的概念,以及它们在实际应用中的作用和意义。
最终我们将通过总结本文的内容,展望线程和实例在未来的发展方向。
1.2 文章结构:本文将首先介绍线程的概念,包括线程是什么以及它的基本特点。
接着将讨论线程在实际应用中的重要性和作用。
在这一部分,我们将探讨线程是如何帮助提高程序的执行效率和并发性能的。
在文章的第三部分,我们将总结线程的相关内容,并介绍线程与实例之间的关系。
最后,我们将展望未来,探讨线程技术的发展趋势及可能的应用领域。
通过本文,读者将对线程这一重要概念有更深入的理解,同时也能够了解线程在实例中的应用和未来的发展方向。
1.3 目的:文章的主要目的是探讨线程和实例在计算机编程中的重要性和关系。
通过深入剖析线程的概念、特点和应用,我们可以更好地理解并掌握多线程编程技术,提高程序的效率和性能。
同时,我们也将探讨线程与实例之间的关系,探讨它们在程序设计中的交互作用。
最终,本文旨在帮助读者更好地理解和利用线程和实例这两个重要的概念,从而提升编程技能和实践能力。
2.正文2.1 线程的概念线程是操作系统中最小的执行单元,是进程中的实际运行单位。
在多任务处理系统中,每个进程都可以包含多个线程,这些线程共享相同的资源,如内存空间、文件以及其他系统资源。
每个线程都拥有自己的程序计数器、栈和寄存器,但是它们可以访问同一个进程中的共享内存,这使得线程之间可以方便快速地通信和共享数据。
与进程相比,线程的创建、撤销和切换等操作都更加高效和轻量级。
java多线程实验报告

Java实验程序设计实验报告实验名称:多线程一:实验目的1、掌握线程和多线程的概念。
2、掌握创建线程的两种方法及其区别。
3、了解线程的启动、终止、同步、互斥和优先级等概念。
二:实验内容1、编写一个程序,其功能是运行之后,其中有一个线程可以输出20次你的学号,另一个线程会输出20次你的姓名。
2、编写一个图形界面程序,运行之后,让其中有一个线程能在界面上“实时”显示系统当前时间(精确到秒获取时间可查询java.util.Calendar类,它包含了多个用于获得系统时间的函数)。
另让一个线程可以在界面上提示当前系统时间下用户该做什么工作(例如当程序判断出系统时间现在是8:00到9:00,则提示用户该上课;现在是23:00到8:00,则提示用户该休息。
具体测试时可以将时间段限制到秒级,以便及时查看到程序运行中提示信息的变化)。
三:实验设计四:实验测试及运行结果实验一;20次输出姓名,学号实验二:一个界面的左边显示当时时间,显示的时间会随时间的改变而改变,右边显示某个时间段该干什么,比如该睡觉,该上课,该自习。
五:问题与总结通过这次实验学会了怎么使用多线程。
六:附录package shiyan6_1;class MyThread implements Runnable {public MyThread() {// 构造函数的代码,根据需要来写}public void run() {for (int i = 1; i <= 20; i++) {System.out.println("第" + i + "次执行线程"+ Thread.currentThread().getName());try {Thread.currentThread().sleep(500);// 睡眠500ms } catch (InterruptedException e) {}}}public static void main(String args[]) {Thread t1 = new Thread(new MyThread(), "学号"); // 创建线程1的对象,并// 通过第二个参数将其命名为thread 1Thread t2 = new Thread(new MyThread(), "姓名"); // 创建线程2的对象,并// 通过第二个参数将其命名为thread 2t1.start(); // 启动两个线程运行t2.start(); // 虽然t2的启动表面上好像在后面,实际上两个线程的执行并无先后之分,}}实验二:package shiyan6_2;import java.awt.FlowLayout;import java.text.SimpleDateFormat;import java.util.Calendar;import javax.swing.JFrame;import javax.swing.JTextArea;public class MyThread {JFrame jf = new JFrame("线程都往界面上显示内容的例子");static JTextArea jta1, jta2;Thread trda = new thread1(); // 线程trdaThread trdb = new thread2(); // 线程trdbpublic MyThread() // 构造函数,生成图形界面{// setBounds(100,100,500,200);jf.setLayout(new FlowLayout());jta1 = new JTextArea(15, 30);jta2 = new JTextArea(15, 30);jf.add(jta1);jf.add(jta2); // 将2个组件添加到界面上jf.setLocation(100, 150);jf.setVisible(true);jf.pack();trda.start(); // 两个线程都启动trdb.start();}public static void main(String args[]) {MyThread frm = new MyThread();}}class thread1 extends Thread // 线程类thread1 {public void run() {int y, m, d, h, mi, s;while(true){Calendar cal = Calendar.getInstance(); // 获取一个Calendar 类的实例对象y = cal.get(Calendar.YEAR); // 获取年份m = cal.get(Calendar.MONTH)+1; // 获取月份,获取的月份是从0到11表示一到十二月d = cal.get(Calendar.DATE); // 获取日期h = cal.get(Calendar.HOUR_OF_DAY); // 获取小时mi = cal.get(Calendar.MINUTE); // 获取分钟s = cal.get(Calendar.SECOND); // 获取秒钟String s1=Integer.toString(y);String s2=Integer.toString(m);String s3=Integer.toString(d);String s4=Integer.toString(h);String s5=Integer.toString(mi);String s6=Integer.toString(s);MyThread.jta1.setText(s1+"年"+s2+"月"+s3+"日"+s4+"时"+s5+"分"+s6+"秒");}}}class thread2 extends Thread // 线程类thread2{public void run() {Calendar cal = Calendar.getInstance();int hour = cal.get(Calendar.HOUR_OF_DAY); // 获取小时int minute = cal.get(Calendar.MINUTE); // 获取分钟if (hour>23||hour<7){MyThread.jta2.append(" 睡觉时间");}else if(hour>7&&hour<17){MyThread.jta2.append(" 上课时间");}else if(hour>17&&hour<23){MyThread.jta2.append(" 自习时间");}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
模块的外部特性:模块的模块名、参数表 模块的内部特性:完成其功能的程序代码和仅供该
模块内部使用的数据 通常是先确定模块的外部特性,再确定其内部特性。
2.模块化和工程
• 函数是最小的模块,若干个紧密相关的函数可 以组成更大的模块--源文件。
• 一条好的原则就是保持模块的紧凑性.即在同 一个源文件中只包含那些在逻辑上与其相关的 函数。
time_count(); /*时间片推进一个*/ } }
线程在电梯控制系统中的使用
//接收输入线程ile(1){
ch=getchar(); //加入代码:将ch翻译成相应请求并保存; time_count();//时间片推进一个; } }
线程1 接收键盘输入
线程2 写文件
写入
读取
全局变量 Ch
1.使用线程实现任务并发
#include <stdio.h> #include <stdlib.h> //使用线程编程时,下面这两个头文件必须包含 #include <winsock.h> #include <winbase.h>
void getInput(void); //线程1要运行的函数 void output(void); //线程2要运行的函数
1. 使用线程实现任务并发 2. 模块化和工程 3. 概要设计要点 4. 时间控制函数 5. 有限状态自动机解题
提纲
4.1-计时函数
while (1){ state_trans(); ();//根据自动机模型决定此刻电梯的状态 print_message();/*输出电梯此刻的状态*/
control(); /*根据控制策略确定下一目标楼层,这在 state_trans()中要用到 */
//进行变量初始化工作
线程在电梯控制系统中的使用
while (1){ state_trans(); ();//根据自动机模型决定此刻电梯的状态 print_message();/*输出电梯此刻的状态*/
control(); /*根据控制策略确定下一目标楼层,这在 state_trans()中要用到 */
• 使用工程来组织多个源文件。 • 将功能紧密相关的若干个函数组成单独的源文件。
1. 使用线程实现任务并发 2. 模块化和工程 3. 概要设计要点 4. 时间控制函数 5. 有限状态自动机解题
提纲
3.概要设计要点
• 概要设计的目的: – 全局把握程序结构:进行程序的模块划分, 设计模块之间如何相互调用来完成程序要求 的功能。
述了引起状态迁移的条件,并且要在文档中附加说明 进入某状态要做的动作。 3. 全局变量:较全面地给出了各个函数要共享的数据。 4. 程序模块化:函数接口说明,函数调用关系说明。 5. 调度算法:给出电梯、小火车调度或者银行调度的算 法。
3-1 用户界面(1)
很漂亮,不过展示的信息太少
点评:界面上增加各层向上向下请求对应的字符,以便于 操作;电梯请求展示区需要再细化,分别显示:向上请求、 向下请求,电梯内请求。
char ch=‘A’; //全局变量
1.使用线程实现任务并发
int main() {
int i; /*创建线程1:从键盘接收字符写入到全局变量ch中 */ DWORD ThreadID1 = 1; HANDLE hRead1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTI NE)getInput,NULL,0,&ThreadID1); /*创建线程2:用于将全局变量ch写入文件*/ DWORD ThreadID2 = 2; HANDLE hRead2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTI NE)output,NULL,0,&ThreadID2);
LPVOID是一个Void类型的指针,也就是说你可以将任意 类型的指针赋值给LPVOID类型的变量。
DWORD是32位无符号整数。
1.使用线程实现任务并发
• lpThreadAttributes表示创建线程的安全属性,NT下有用。可赋值 为NULL。
• dwStackSize指定线程栈的尺寸,如果为0则与进程主线程栈相同。 • lpStartAddress指定线程开始运行的地址。赋值为指向函数的指针,
DWORD ThreadID1 = 1;
HANDLE hRead1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)getInput, NULL,0,&ThreadID1);
1.使用线程实现任务并发
• 1.使用线程实现任务并发
main函数中创建两个线程,线程1从键盘接 收字符数据写入变量ch中,线程2读取ch写 入文件中。
电梯状 态计算 和输出
接收服 务请求
• 因此我们可以考虑在模
线程共享内存区
拟电梯控制系统中设计
一个线程专门用于接收 电梯服务请求,另一个 接收服务请求:接收电梯请求,将 线程实行电梯的状态计 请求保存到内存。
算和状态输出
电梯状态计算和输出:从共享内存
区读取电梯请求,计算下一目标楼
层,从而确定电梯的下一状态。
即函数名。 • lpParameter表示传递给线程的32位的参数。 若无参数则赋值为
NULL。 • dwCreationFlags表示是否创建后挂起线程(取值
CREATE_SUSPEND),挂起后调用ResumeThread继续执行。若不 挂起则赋值为0。 • lpThreadId用来存放返回的线程ID。
4.1-计时函数
#include “stdio.h”
#include “stdlib.h”
#include “time.h”
int main( void )
{
long i = 10000000L;
clock_t start, finish;
double duration;
/* 测量一个事件持续的时间*/
time_count(); /*时间片推进一个*/ } }
4.1-计时函数
• clock_t clock( void ); ANSI标准库中的time.h头文件,其中定义了日期和时 间的处理函数。
• 这个函数返回从“启动程序”到“程序中调用clock() 函数”之间的CPU时钟计时单元(clock tick)数,在 MSDN中称之为挂钟时间(wal-clock)。其中clock_t 是用来保存时间的数据类型,长整型。
– 定义关键变量,用来存储各模块共享的数据; 定义常量。
– 设计关键的算法,主要是控制策略,提前对 关键的、较难解决的问题进行处理。
3.概要设计要点
概要设计主要从以下5个方面考虑: 1. 用户界面:界面友好,要能从界面提示信息了解电梯/
火车/银行的状态和请求。 2. 自动机模型:有自动机状态迁移图,状态迁移图上描
• clock tick:CPU时钟计时单元,时间长短由CPU控制。 一个clock tick不是CPU的一个时钟周期,而是C/C++ 的一个基本计时单位。
• 常量CLOCKS_PER_SEC,它表示一秒钟会有多少个 时钟计时单元 。
• 可以使用公式clock()/CLOCKS_PER_SEC来计算一个 进程自身的运行时间。
3-1 用户界面(2)
电梯内部描述
3-2 自动机模型
思考:该图有什么待改进之处?
3-3 全局变量
• 函数之间如何通信?-全局变量或者参数 • 线程之间如何通信?-全局变量或者参数
• 全局变量设计考虑要全面; • 应明确给出定义,如:
int destLayer;//记录电梯下一目标服务 楼层
printf( “Time to do %ld empty loops is ”, i );
– 进程是计算机资源分配的基本单位。设置一个进程 要占用相当一部分处理器时间和内存资源
– 大多数操作系统不允许进程访问其他进程的内存空 间,进程间的通信很不方便,编程模型比较复杂
1.使用线程实现任务并发
• 线程
– 一个程序中多段代码同时并发执行,称为多线程 – 通过多线程,一个进程表面上看同时可以执行一个
2.模块化和工程
• 模块化:把程序划分成独立命名且可独立访问的模块, 每个模块完成一个子功能,所有模块集成起来构成的 整体可完成用户的所有需求。
复杂问题 分解 较小问题 从整体上把握问题,隐蔽细节
• 模块化意义 降低了系统的复杂性,使系统容易修改和重用; 推动系统各部分的并行开发,提高开发效率。
} }
写入
全局变量 Ch
1.使用线程实现任务并发
void output(void) {
线程2 写文件
long int i; FILE * cfPtr=NULL;
读取
if( (cfPtr=fopen("data.txt","w"))==NULL) 全局变量
printf("can't open file\n");
1. 使用线程实现任务并发 2. 模块化和工程 3. 概要设计要点 4. 时间控制函数 5. 有限状态自动机解题
提纲
2.模块化和工程
• 模块的定义 – 一般把用一个名字就可调用的一段程序称为“模 块”,如子程序、函数等。 – 模块的基本属性:
功能:描述该模块实现什么功能 逻辑:描述模块内部怎么做 状态:该模块使用时的环境和条件
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, DWORD lpThreadId);