1、进程和线程的区别主要有哪些?为什么要使用线程?
进程是系统中正在运行的一个应用程序,线程是指进程中执行运行的最小单位。
进程必须至少包括一个线程,线程依附于进程存在。
线程更加经济,启动快、退出快、对系统资源冲击少。而启动一个进程,必须
为进程分配内存,初始化。
2 、解决线程同步的方式主要有哪些?
主要有四种:
(1)互斥量(Mutex)
Mutex对象的状态在它不被任何线程拥有时才有信号,而当它被线程拥有时则无
信号。Mutex对象很适合用来协调多个线程对共享资源的互斥访问。可以按下列步骤
使用该对象:
1.建立互斥体对象,得到句柄:
HANDLE CreateMutex();
2.在线程可能产生冲突的区域前(即访问共享资源之前)调用〜七& 说 ^⑷ 句 抓
将句柄传给函数,请求占用互斥对象:
dwWaitResult = WaitForSingIeObject(hMutex,5000L);
3.共享资源访问结束,释放对互斥体对象的占用:
ReleaseMutex(hMutex);
互斥体对象在同一时刻只能被一个线程占用,当互斥体对象被一个线程占用时,
若有另一线程想占用它,则必须等到前一线程释放后才能成功。
(2)信号量(Semaphore)
信号对象允许同时对多个线程共享资源进行访问,在创建对象时指定最大可同时
访问的线程数。当一个线程申请访问成功后,信 号 对 象 中 的 计 数 器 减 1, 调用
尺0^56860^匕0比函数后,信号对象中的计数器加1。其中,计数器值大于或等于0 ,
但小于或等于创建时指定的最大值。如果一个应用在创建一个信号对象时将其计数器
的 初 始 值 设 为 0 , 则 阻 寒 了 其 他 线 程 ,保 护 了 资 源 。等 初 始 化 完 成 后 ,调用
ReleaseSemaphore函数将其计数器增加至最人值,则可进行正常的存取访问。可以按
下列步骤使用该对象:
1.创建信号对象:
HANDLE CreateSemaphore();
或者打开一个信号对象:
HANDLE OpenSemaphore();
2. 在线程访问共享资源之前调用WaitForSingleObject。
3. 共享资源访问完成后,应释放对信号对象的占用:
ReleaseSemaphore();
(3)事件(Event)
事件对象(Event)是最简单的同步对象,它包括有信号和无信号两种状态。在线
程访问某一资源之前,需要等待某一事件的发生,这时用事件对象最合适。例如:只
有在通信端口缓冲区收到数据后,监视线程才被激活。
事件对象是用CreateEvent函数建立的。该函数可以指定事件对象的类和事件的初
始状态。如果是手工重置事件,那么它总是保持有信号状态,直到用Reseffivent函数
重置成无信号事件。如果是自动重置事件,那么它的状态在单个等待线程释放后会自
动变为无信号的。用 SetEvem可以把事件对象设置成有信号状态。在建立事件时,可
以为对象命名,这样其他进程中的线程可以用OpenEvent函数打开指定名字的事件对
象句柄。
(4)临界区(Critical Section)
在排斥区中异步执行时,它只能在同一进程的线程之间共享资源处理。虽然此时
上面介绍的儿种方法均可使用,但是,使用排斥区的方法则使同步管理的效率更高。
使用时先定义一个CRIT1CAL_SECTI0N结构的排斥区对象,在进程使用之前调
用如卜函数对对象进行初始化:
VOID InitializeCriticalSection(LPCRITICAL_SECTION)
当一个线程使用排斥区时,调用函数EnterCriticalSection或 TryEnterCriticalSection。
当要求占用、退出排斥区时,调用函数LeaveCriticalSection释放对排斥区对象的
占用,供其他线程使用。
3 、 如何利用Win32 API和 MFC 进行多线程程序的编写?
4 、 在什么情况下使用多线程?
决定多线程性能的最主要因素是基于I/O的计算和基于CPU的计算的比列,
决定是否采用多线程的主要条件是前台的用户响应。