11程序设计实践6w-线程、模块化、时间函数和设计问题

上传人:L** 文档编号:334511560 上传时间:2022-09-07 格式:PPTX 页数:77 大小:746.41KB
返回 下载 相关 举报
11程序设计实践6w-线程、模块化、时间函数和设计问题_第1页
第1页 / 共77页
11程序设计实践6w-线程、模块化、时间函数和设计问题_第2页
第2页 / 共77页
11程序设计实践6w-线程、模块化、时间函数和设计问题_第3页
第3页 / 共77页
11程序设计实践6w-线程、模块化、时间函数和设计问题_第4页
第4页 / 共77页
11程序设计实践6w-线程、模块化、时间函数和设计问题_第5页
第5页 / 共77页
点击查看更多>>
资源描述

《11程序设计实践6w-线程、模块化、时间函数和设计问题》由会员分享,可在线阅读,更多相关《11程序设计实践6w-线程、模块化、时间函数和设计问题(77页珍藏版)》请在金锄头文库上搜索。

1、 模块化设计问题模块化设计问题1 提纲提纲1.使用线程实现任务并发使用线程实现任务并发2.模块化和工程模块化和工程3.概要设计要点概要设计要点4.时间控制函数时间控制函数5.有限状态自动机解题有限状态自动机解题2 1.使用线程实现任务并发问题的引出:以电梯控制系统为例问题的引出:以电梯控制系统为例目前能想到的程序主体结构目前能想到的程序主体结构main()while(1)state_trans();/计算此刻电梯的状态计算此刻电梯的状态print_message();/输出电梯此刻的状态输出电梯此刻的状态,包括动画包括动画get_input();/接收当前时刻的新输入(包括新目接收当前时刻的新

2、输入(包括新目标和新呼叫)标和新呼叫)control();/*根据控制策略确定下一目标楼层,根据控制策略确定下一目标楼层,在在state_trans()中要用到中要用到*/time_count();/时间片推进一个时间片推进一个思考:上述结构不合理之处?思考:上述结构不合理之处?3 1.使用线程实现任务并发上述结构不合理之处上述结构不合理之处:计算和输出电梯状态与接收服务计算和输出电梯状态与接收服务请求是串行的,与现实中的电梯运行不符!请求是串行的,与现实中的电梯运行不符!程序结构的改进:程序结构的改进:从上述代码中删除从上述代码中删除get_input(),从而实现每隔一小段时,从而实现每隔

3、一小段时间就刷新电梯当前状态间就刷新电梯当前状态main()while(1)state_trans();/计算此刻电梯的状态计算此刻电梯的状态print_message();/输出电梯此刻的状态输出电梯此刻的状态control();/*根据控制策略确定下一目标楼层,这根据控制策略确定下一目标楼层,这在在state_trans()中要用到中要用到*/time_count();/时间片推进一个时间片推进一个4 1.使用线程实现任务并发但是,程序必须要能接收电梯服务请求,如何但是,程序必须要能接收电梯服务请求,如何处理服务请求的输入?处理服务请求的输入?理想状态:理想状态:电梯服务请求的接收和电梯状

4、态的计算输出电梯服务请求的接收和电梯状态的计算输出能同时进行,互不影响能同时进行,互不影响但是,能否实现?但是,能否实现?答案是:使用线程答案是:使用线程电梯状电梯状态计算态计算和输出和输出共享内存区共享内存区接收服接收服务请求务请求5 1.使用线程实现任务并发进程进程一个正在运行的程序的实例,是一个程序在其自身一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动,例如的地址空间中的一次执行活动,例如n用字处理软件编辑文稿时,同时打开用字处理软件编辑文稿时,同时打开mp3播放程序听播放程序听音乐,这两个独立的程序在同时运行,称为两个进程音乐,这两个独立的程序在同时运行,称为两

5、个进程进程是资源申请、调度和独立运行的单位进程是资源申请、调度和独立运行的单位6 1.使用线程实现任务并发线程线程线程是系统分配处理器时间资源的基本单元。对于操作系统线程是系统分配处理器时间资源的基本单元。对于操作系统而言,其调度单元是线程(而言,其调度单元是线程(为线程提供时间片,线程在自己为线程提供时间片,线程在自己的时间片内运行)的时间片内运行)。一个程序中多段代码同时并发执行,称为多线程一个程序中多段代码同时并发执行,称为多线程n譬如用譬如用word同时打开多个文档进行编辑,用同时打开多个文档进行编辑,用IE浏览浏览器同时访问多个网站器同时访问多个网站通过多线程,一个通过多线程,一个进

6、程进程表面上看同时可以执行一个以上表面上看同时可以执行一个以上的任务的任务并发并发7 线程(续)线程(续)一个进程至少包括一个线程(称为主线程)。一个进程至少包括一个线程(称为主线程)。一个进程从主线程的执行开始进而创建一个一个进程从主线程的执行开始进而创建一个或多个附加线程,就是所谓基于多线程的多或多个附加线程,就是所谓基于多线程的多任务。任务。线程自己不拥有系统资源,但它可与同属一线程自己不拥有系统资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资个进程的其它线程共享进程所拥有的全部资源源8 1.使用线程实现任务并发在在C程序中要创建线程,可以调用程序中要创建线程,可以调用Wind

7、ows操作系统提供的创操作系统提供的创建线程的函数建线程的函数CreateThread:HANDLECreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes,DWORDdwStackSize,LPTHREAD_START_ROUTINElpStartAddress,LPVOIDlpParameter,DWORDdwCreationFlags,LPDWORDlpThreadId);LPVOID是一个是一个Void类型的指针,也就是说你可以将任意类类型的指针,也就是说你可以将任意类型的指针赋值给型的指针赋值给LPVOID类型的变量。类型的变量。DWO

8、RD是是32位无符号整数。位无符号整数。9 1.使用线程实现任务并发lpThreadAttributes表示创建线程的安全属性,表示创建线程的安全属性,NT下有用。可赋值下有用。可赋值为为NULL。dwStackSize指定线程栈的尺寸,如果为指定线程栈的尺寸,如果为0则与进程主线程栈相同。则与进程主线程栈相同。lpStartAddress指定线程开始运行的地址。赋值为指向函数的指针,指定线程开始运行的地址。赋值为指向函数的指针,即函数名。该函数的名称任意,但函数类型必须遵照下述声明形式即函数名。该函数的名称任意,但函数类型必须遵照下述声明形式:DWORDWINAPIThreadProc(LP

9、VOIDlpParameter);否则需要进否则需要进行强制类型转换行强制类型转换lpParameter表示传递给线程的表示传递给线程的32位的参数(数值或指针)。位的参数(数值或指针)。若无若无参数则赋值为参数则赋值为NULL。dwCreationFlags表示是否创建后挂起线程表示是否创建后挂起线程(取值取值CREATE_SUSPENDED表示挂起,取值表示挂起,取值0表示创建后立即运行表示创建后立即运行),挂起后调用挂起后调用ResumeThread继续执行。若不挂起则赋值为继续执行。若不挂起则赋值为0。lpThreadId用来存放返回的线程用来存放返回的线程ID。DWORDThread

10、ID1=1;HANDLEhRead1=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)getInput,NULL,0,&ThreadID1);10#include#includeDWORDWINAPIFun1Proc(LPVOIDlpParameter);intmain()HANDLEhThreadl;/hThreadl=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);/CloseHandle(hThreadl);/printf(mainthreadisrunningn);/return0;11DWORDWINAPIF

11、un1Proc(LPVOIDlpParameter)printf(hThreadlisrunningn);return0;例例1 12#include#includeDWORDWINAPIFun1Proc(LPVOIDlpParameter)intmain()HANDLEhThreadl;/hThreadl=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);/CloseHandle(hThreadl);/printf(mainthreadisrunningn);/Sleep(10);/让线程睡眠让线程睡眠10毫秒毫秒return0;例例2#include#in

12、cludeintindex=0;DWORDWINAPIFun1Proc(LPVOIDlpParameter);intmain()HANDLEhThreadl;/hThreadl=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);/CloseHandle(hThreadl);/while(index+1000)printf(mainthreadisrunningn);/return0;13例例3DWORDWINAPIFun1Proc(LPVOIDlpParameter)while(index+1000)printf(hThreadlisrunningn);ret

13、urn0;14 15#include#includeinttickets=100;DWORDWINAPIFun1Proc(LPVOIDpPararneter)while(tickets0)printf(“thread1sellticket:%dn”,tickets-);return0;DWORDWINAPIFun2Proc(LPVOIDpPararneter)while(tickets0)printf(“thread2sellticket:%dn”,tickets-);return0;intmain()HANDLEhThread1=CreateThread(NULL,0,Fun1Proc,NU

14、LL,0,NULL);HANDLEhThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(hThread1);CloseHandle(hThread2);Sleep(4000);return0;16 17 线程的同步线程的同步利用互斥对象利用互斥对象(mutex)实现线程的同步,互斥对象能实现线程的同步,互斥对象能够确保线程拥有对单个资源的互斥访问权。够确保线程拥有对单个资源的互斥访问权。3个操作个操作n互斥对象的创建互斥对象的创建n互斥对象的释放互斥对象的释放n互斥对象的请求互斥对象的请求18 互斥对象的创建HANDLE

15、CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL binitialOwner,LPCTSTR lpNarne)nlpMutexAttributes:可以给该参数传递 NULL值,让互斥对象使用默认的安全性nbinitialOwner:BOOL类型,指定互斥对象初始的拥有者。如果该值为真,则创建这个互斥对象的线程获得该对象的所有权;否则,该线程将不获得所创建的互斥对象的所有权。nlpName:指定互斥对象的名称。如果此参数为 NULL.则创建一个匿名的互斥对象。如果调用成功,该函数将返回所创建的互斥对象的句柄19 互斥对象的释放BO

16、OL ReleaseMutex(HANDLE hMutex);ReleaseMutex函数只有一个HANDLE类型的参数,即需要释放的互斥对象的句柄。该函数的返回值是BOOL类型,如果函数调用成功,返回非0值;否则返回0值。20 互斥对象的请求DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);Handle:所请求的互斥对象的句柄。一旦互斥对象处于有信号状态,则该函数就返回。如果该互斥对象始终处于无信号状态,即未通知的状态,则该函数就会一直等待,这样就会暂停线程的执行。dwMilliseconds:指定等待的时间间隔,以毫秒为单位。如果指定的时间间隔己过,即使所请求的对象仍处于无信号状态,WaitForSingleObject函数也会返回。如果将此参数设置为0,那么 WaitForSingleObject函数将测试该对象的状态并立即返回;如果将此参数设置为INFINITE,则该函数会永远等待,直到等待的对象处于有信号状态才会返回。调用WaitForSingleObject函数后,该函数会一直等待,只有在以下两种情

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 经营企划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号