软件工具与环境考试要点Word文档格式.docx
《软件工具与环境考试要点Word文档格式.docx》由会员分享,可在线阅读,更多相关《软件工具与环境考试要点Word文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
④应用层:
一特定的基本层为基础,但可包括一些补充工具,借以更好地支援各种应用软件的研制。
8.软件开发过程
软件生存期也可以分为三个大的阶段:
计划阶段(软件计划和需求分析)、开发阶段(设计、编码和测试)和维护阶段(改正性维护、完善性维护和适应性维护)。
9.软件开发环境与工具的发展方向
(1)智能化
(2)网络化(3)一体化(4)标准化
10.CASE技术计算机辅助软件工程技术可以简单地定义为软件开发的自动化,通常简称为CASE技术。
第二章
1.多任务?
多线程?
进程?
多任务:
是相对与操作系统而言,指的是同一时间执行多个程序的能力,虽然这么说,但是实际上在只有一个CPU的条件下不可能同时执行两个以上的程序。
CPU在程序之间做高速的切换,使得所有的程序在很短的时间之内可以得到更小的CPU时间,这样从用户的角度来看就好象是同时在执行多个程序。
多线程:
相对于操作系统而言,指的是可以同时执行同一个程序的不同部分的能力,每个执行的部分被称为线程。
所以在编写应用程序时,我们必须得很好的设计以避免不同的线程执行时的相互干扰.
进程是装入内存中即将执行的程序,可以包含一个或多个运行在它的上下文环境内的线程。
在操作系统技术中,进程和线程的出现提高了系统的并行性,从而使应用程序更有效地利用系统资源,多线程的应用程序设计也就应运而生了.
2.进程和线程的区别
进程就是应用程序的实例。
每个进程都有自己私有的虚拟地址空间。
每个进程都有一个主线程,但可以建立另外的线程。
进程中的线程是并行执行的,每个线程占用CPU的时间由系统划分。
一个进程对应着一段程序,它是由一些在同一个程序里面独立的、同时运行的线程组成的。
线程是系统调度的基本单位,线程有时也被称为并行运行在程序里的轻量级进程,这是因为它的运行依赖与进程提供的上下文环境,并且使用的是进程的资源。
进程中的所有线程共享进程的虚拟地址空间,
3.进程的调度
在一个进程里,线程的调度有抢占式或者非抢占的模式。
在抢占模式下,操作系统负责分配CPU时间给各个进程,一旦当前的进程使用完分配给自己的CPU时间,操作系统将决定下一个占用CPU时间的是哪一个线程。
在非抢占的调度模式下,每个线程可以需要CPU多少时间就占用CPU多少时间。
4.线程的种类
线程分用户界面线程和工作者线程两种。
用户界面线程拥有自己的消息循环来处理界面消息,可以与用户进行交互。
工作者线程没有自身的消息循环,一般用来完成后台工作。
5.线程的创建,启动和终止
线程的创建:
工作者线程创建,首先完成控制函数的编写,然后用函数AfxBeginThread来启动线程创建用户界面线程,那么必须从CWinThread派生一个新类。
进程主线程的CWinApp类就是CWinThread的派生类,,程序中默认的WinMain()函数调用CWinApp:
:
Run(),再调用CWinThread:
Run()函数以建立消息循环。
线程的启动:
当使用全局函数AfxBeginThread()创建一个工作者线程时,参数dwCreateFlags指定了线程的初始状态,通常为0,那么线程在创建后立即执行,如果为CREATE_SUSPENDED,则线程在创建后就被挂起。
被挂起的线程直到其他线程调用ResumeThread()函数时,此线程才能继续执行。
线程的终止:
线程调用ExitInstance()。
•
线程函数返回,即线程隐含调用了ExitInstance()。
函数原形为VOIDExitInstance(UNITfuExitCode)。
这个函数为调用该函数的线程设置了退出码fuExitCode后,就终止该线程。
•函数ExitProcess被进程的任一线程显示或隐含调用。
•用线程的句柄调用TerminateThread,此时Windows不通知DLL。
•用进程句柄调用TerminateProcess。
调用全局函数AfxEndThread。
6.线程的优先级
•THREAD_PRIORITY_IDLE在一般进程中,线程基本优先级为1;
对于进程调度优先于其他所有进程的进程,线程的基本优先级为16。
•THREAD_PRIORITY_LOWEST基本优先级比所在进程低
•THREAD_PRIORITY_BELOW_NORMAL基本优先级比所在进程略低
•THREAD_PRIORITY_NORMAL基本优先级比所在进程相同
•THREAD_PRIORITY_ABOVE_NORMAL基本优先级比所在进程略高
•THREAD_PRIORITY_HIGHEST基本优先级比所在进程高
•THREAD_PRIORITY_CRITICAL最高的线程优先级
7.线程间的通信
•最简单的线程间的通讯可以仅用一个简单的布尔型变量来实现。
•通常需要使用同步类来实现线程之间的通讯与控制。
对于线程和主应用程序之间的通讯,可以通过消息的发送与处理来完成,通过调用:
:
PostMessage()或CWinThread:
PostThreadMessage()来通讯。
8.同步对象
同步对象包括:
CSyncObject、CSemaphore、CMutex、CCriticalSection、CEvent;
同步访问对象包括:
CmultiLock和CsingleLock
9.线程同步对象的类型与用途
Event(事件)通知已发生事件的一个或多个等待函数,作为标志在线程间传递信号
CriticalSection(临界区)用于获得对共享资源的访问
Mutex(互斥量)一次只能有一个线程拥有,可用于多进程
中的线程同步,能使线程协调共享资源的互斥访问
Semaphore(信号灯)维持到某个最大值之间的计数,限制同时访问共享资源的线程数量
10.同步对象函数
Event:
SetEvent设置一个事件可用(有标记),并释放某些等待线程
PulsetEvent设置一个事件可用(有标记),并释放某些等待线程,设置该事件无效(无标记)
ResetEvent设置事件无效(无标记)
临界区:
当一个线程拥有临界区时,如果其他的线程需要访问这个被锁定的资源,则这个线程必须挂起自身。
一个CCriticalSection对象允许在同一时刻仅有一个线程访问一个资源或一段代码。
调用其Lock()方法锁定资源;
为释放资源,可以调用对象的Unlock()方法
互斥量:
互斥(Mutex)允许一个线程对资源进行互斥访问,当在某时刻只允许一个线程修改数据或其他某些被控资源一次只能有一个线程拥有Mutex对象。
线程可以通过使用CreateMutex函数来创建Mutex对象,拥有线程使用ReleaseMutex函数释放Mutex对象。
•互斥量与临界区之间的最大区别在于临界区只用于进程内的通讯,而互斥量可以用于多个进程之间的通讯。
信号灯对象是维护0到指定的最大值之间计数的同步对象。
每次由于信号灯有信号而使等待函数返回时,信号灯计数减一,ReleaseSemaphore函数以指定量增加信号灯的计数。
第三章
1.多媒体文件
多媒体文件一般被称为RIFF文件,即资源交互文件格式,RIFF格式是面向部分(Chunk)的。
MFC为处理RIFF文件专门提供了一套多媒体I/O函数,这些函数都有前缀mmio。
比如mmioOpen是打开RIFF文件,mmioDescend可以进入RIFF文件的部分。
BMP文件开始通常依次是14字节的文件头,40字节的位图信息,颜色表(真彩位图没有),最后是图像数据,位图文件中的数据是从下到上(而不是从上到下)、从左到右方式存储的。
2.设备相关位图(DDB)与设备无关位图(DIB)的区别
设备相关位图DDB:
DDB不具有自己的调色板信息,他的颜色模式必须与输出设备相一致。
由于DDB高度依赖输出设备,所以DDB只能存在于内存中,它要么在视频内存中,要么在系统内存中。
设备无关位图DIB:
DIB具有自己的调色板信息,他可以不依赖系统的调色板。
由于他不依赖于设备,所以通常用它来保存文件,如.bmp格式的文件就是DIB.
3.媒体控制接口MCI
MCI(媒体控制接口)向Windows程序提供了在高层次上控制媒体设备接口的能力。
为了唯一地区分MCI驱动程序,MCI引入设备名,放在SYSTEM.INI文件的[MCI]段中。
4.MCI编程接口
•MCI编程接口可以利用近似英语的句法与MCI设备通信,被称为串方式。
•MCI最常用的另一种方式是消息方式,即发送WINDOWS消息
•MCIERRORmciSendCommand(
•MCIDEVICEIDIDDevice,//设备的ID,在打开设备时不用该参数
•UINTuMsg,//命令消息
•DWORDdwCommand,//命令消息的标志
•DWORDdwParam//指向包含命令消息参数的结构
•);
//若成功则返回0,否则返回错误码
5.MCI的接口程序(波形音频)
①打开波形音频
•WORDm_wDeviceID;
//MCI设备名
•CStringFilename;
//波形文件名
•…
•MCI_OPEN_PARMSOpenParms;
//MCI设备打开参数
•OpenParms.lpstrDeviceType=“waveaudio”;
//设备种类
•OpenParms.lpstrElementName=Filename;
•If(mciSendCommand(0,MCI_OPEN,MCI_OPEN_ELEMENT
•|MCI_OPEN_TYPE,(DWORD)(LPVOID)&
OpenParms))
•returnFALSE;
•m_wDeviceID=OpenParms.wDeviceID;
②播放波形音频
•MCI_PLAY_PARMSPlayParms;
//播放参数
•mciSendCommand(m_wDeviceID,MCI_SEEK,
•MCI_SEEK_TO_START,NULL);
•//将播放指针定位在波形文件的开始
•If(mciSendCommand(0,MCI_PLAY,MCI_NOTIFY,
•(DWORD)(LPVOID)&
PlayParms))
•Else
•returnTURE;
③关闭波形音频设备
•mciSendCommand(m_wDeviceID,MCI_STOP,
•MCI_WAIT,NULL);
•//先停止播放当前的声音
•mciSendCommand(m_wDeviceID,MCI_CLOSE,
•MCI_NOTIFY,NULL);
•//关闭设备
④获取波形音频参数
•DWORDSampleRate;
//采样率
•MCI_STATUS_PARAMSStatusParms;
//状态参数
•StatusParms.dwItems=MCI_WAVE_STATUS_SAMPLESPERSEC;
•//dwItems设置需要获得参数的信息标志
•If(mciSendCommand(m_wDeviceID,MCI_STATUS,MCI_WAIT|
•MCI_STATUS_ITEM,(DWORD)(LPVOID)&
StatusParms))
•return-1;
•SampleRate=StatusParms.dwReturn;
•//结果返回到dwReturn成员中
•MCI_STATUS_PARAMS参数是重要参数,在它的属性dwItems填入需求的参数宏,属性dwReturn就会返回相应的值。
⑤设置波形音频参数
•intnChannels=2;
•MCI_WAVE_SET_PARAMSSetParms;
//设置参数对象
•SetParms.nChannels=nChannels;
//设置声道数
•(mciSendCommand(m_wDeviceID,MCI_SET,MCI_WAIT|
•MCI_WAVE_SET_CHANNELS,(DWORD)(LPVOID)&
SetParms))
•对应不同的音频设备,设置的参数对象是不同的,对象中的属性根据不用的设备也有所不同。
比如MIDI的参数对象就是MCI_SEQ_SET_PARAMS。
⑥定位播放位置
•BOOLSeekTo(intnMinute,intnSecond)
•{MCI_SEEK_PARAMSSeekParms;
•SeekParms.dwTo=(Min*60+Sec)*1000;
•mciSendCommand(m_wDeviceID,MCI_PAUSE,0,NULL);
•If(mciSendCommand(m_wDeviceID,MCI_SEEK,MCI_TO|
•MCI_WAIT,(DWORD)(LPVOID)&
SeekParms))
•}
⑦取得当前位置
•MCI_STATUS_PARMSStatusParms;
•StatusParms.dwItem=MCI_STATUS_POSITION;
•mciSendCommand(m_wDeviceID,MCI_STATUS,MCI_WAIT|MCI_STATUS_ITEM,(DWORD)(LPVOID)&
StatusParms);
•DWORDdwPos=StatusParms.dwReturn;
•intMin=StatusParms.dwReturn/1000/60;
//分
•intSec=(StatusParms.dwReturn-min*60000)/1000;
//秒
•intFram=StatusParms.dwReturn-(min*60+sec)*1000;
//毫秒
6.MCI接口程序(视频)
①打开播放数字视频的设备
•MCI_DGV_OPEN_PARMSOpenParms;
•OpenParms.lpstrDeviceType=“avivideo”;
•OpenParms.lpstrElementName=(LPSTR)Filename.GetBuffer(0);
•OpenParms.hWndParent=pWnd->
m_hwnd;
//将要播放视频的主窗口
•OpenParms.dwStyle=WS_CHILD|WS_VISIBLE;
//窗口属性
•If(mciSendCommand(0,MCI_OPEN,MCI_WAIT|MCI_OPEN_TYPE
•|MCI_OPEN_ELEMENT|MCI_DGV_OPEN_WS|
•MCI_DGV_OPEN_PARENT,(DWORD)(LPVOID)&
②设置数字视频的播放
•MCI_DGV_SET_PARMSSetParms;
•SetParms.dwAudio=MCI_SET_AUDIO_ALL;
•DWORDdwFlags=MCI_SET_AUDIO;
•If(bSound)
•dwFlags|=MCI_SET_ON;
•ElsedwFlags|=MCI_SET_OFF;
(是否播放声音)
•mciSendCommand(m_wDeviceID,MCI_SET,dwFlags,
SetParms);
③播放数字视频
•MCI_DGV_PLAY_PARMSPlayParms;
•PlayParms.dwCallback=NULL;
•PlayParms.dwFrom=GetFrames();
•If(mciSendCommand(m_wDeviceID,MCI_PLAY,MCI_FROM,
•m_bPaused=FALSE;
//暂停标志为假
•M_bPlaying=TRUE;
//播放标志为真
•注:
这里可以设置时间格式为帧MCI_FORMAT_FRAMES,使用参数MCI_STATUS_POSITION返回的就是帧数
③关闭数字视频
•//先停止播放
//关闭设备
第四章
1.动态链接库
DLL是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。
动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。
2.动态静态链接库的区别
静态链接库与动态链接库都是共享代码的方式,如果采用静态链接库,则无论你愿不愿意,lib中的指令都被直接包含在最终生成的EXE文件中了。
但是若使用DLL,该DLL不必被包含在最终EXE文件中,EXE文件执行时可以“动态”地引用和卸载这个与EXE独立的DLL文件。
静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库,而在动态链接库中还可以再包含其他的动态或静态链接库。
3.部分代码的注释
①#pragmacomment(lib,"
..\\debug\\libTest.lib"
) //指定与静态库一起连接代码中#pragmacomment(lib,"
)的意思是指本文件生成的.obj文件应与libTest.lib一起连接。
②hDll=LoadLibrary(“..\\Debug\\dllTest.dll”);
通过Win32Api函数LoadLibrary动态加载了DLL模块并将DLL模块句柄赋给了hDll;
③addFun=(lpAddFun)GetProcAddress(hDll,"
add"
);
通过Win32Api函数GetProcAddress得到了所加载DLL模块中函数add的地址并赋给了addFun。
经由函数指针addFun进行了对DLL中add函数的调用;
4)FreeLibrary(hDll);
在函数main中通过Win32Api函数FreeLibrary释放了已经加载的DLL模块。
4.导出函数
DLL中导出函数的声明有两种方式:
一种为在函数声明中加上__declspec(dllexport);
另外一种方式是采用模块定义(.def)文件声明,.def文件为链接器提供了有关被链接程序的导出、属性及其他方面的信息。
•;
lib.def:
导出DLL函数
LIBRARYdllTest
EXPORTS
add@1
•.def文件的规则为:
(1)LIBRARY语句说明.def文件相应的DLL;
(2)EXPORTS语句后列出要导出函数的名称。
可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号将发挥其作用);
(3).def文件中的注释由每个注释行开始处的分号(;
)指定,且注释不能与语句共享一行。
5.DLL的调用方式
LoadLibrary-GetProcAddress-FreeLibrary”系统Api提供的三位一体“DLL加载-DLL函数地址获取-DLL释放”方式,这种调用方式称为DLL的动态调用。
静态调用方式的特点:
由编译系统完成对DLL的加载和应用程序结束时DLL的卸载。
当调用某DLL的应用程序结束时,若系统中还有其它程序使用该DLL,则Windows对DLL的应用记录减1,直到所有使用该DLL的程序都结束时才释放它。
静态调用方式不再需要使用系统API来加载、卸载DLL以及获取DLL中导出函数的地址
6.DLLMAIN函数
Windows在加载DLL的时候,需要一个入口函数,就如同控制台或DOS程序需要main函数、WIN32程序需要WinMain函数一样。
Windows必须查找并执行DLL里的DllMain函数作为加载DLL的依据,它使得DLL得以保留在内存里。
这个函数并不属于导出函数,而是DLL的内部函数。
7.DLLMAIN函数说明
DllMain在DLL被加载和卸载时被调用,在单个线程启动和终止时,DLLMain函数也被调用
进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,句柄代表了DLL模块在进程虚拟空间中的起始地址。
MAKEINTRESOURCE是一个通过序号获取函数名的宏MAKEINTRESOURCE
(1))值得留意,它直接通过.def文件中为add函数指定的顺序号访问add函数
8.导出变量
1.DLL定义的全局变量可以被调用进程访问;
DLL也可以访问调用进程的全局数据
/*文件名:
lib.h *//*文件名:
lib.cpp*/
#ifndefLIB_H#include"
lib.h"
#include<
windows.h>
#defineLIB_HintdllGlobalVar;
………..
externintdllGlobalVar;
dll