开发出高性能的服务器端程序,必然离不开多线程,当然如果你追求的首位是稳定 而不是效率,你也可以选择单线程,然后用高昂的硬件来提升性能,这必须你要有雄厚的资本。
如果你没有那么多票子,还是用多线程吧,虽然很多人谈起色变,但只要控制的好,依然能很好的为我所用,脱缰的野马总有人能制服,你也可以。
多线程唯一需要解决的问题是 同步问题
首先解决两个名词
1:信号量
是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。
Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。
2:互斥
为了更好的理解,分别举例说明
1:信号量
以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。
在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。
2:互斥
比如你买火车票,当售票员A确定操作后,系统将锁定住,其他售票员B如果此时也进行取票操作,系统会让B等待A操作完后继续操作
信号量和互斥 原理是解决多线程同步的方式,具体看你的应用了。以下是常用API
信号的获得 DWORD WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);
第二个参数为等待时间,使用0表示无限等待
信号的释放 BOOL ReleaseSemaphore(
__in HANDLE hSemaphore,
__in LONG lReleaseCount,
__out_opt LPLONG lpPreviousCount
);
取得控制权,如果对象处于排斥状态,则等待
VOID EnterCriticalSection(
__inout LPCRITICAL_SECTION lpCriticalSection
);
尝试取得控制权,return 是否成功取得控制权
BOOL TryEnterCriticalSection(
__inout LPCRITICAL_SECTION lpCriticalSection
);
等待并取得控制权
@param time 等待的最大时间,时间为0表示尝试
@return 是否取得控制权
DWORD WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);
放弃控制权 即解锁
VOID LeaveCriticalSection(
__inout LPCRITICAL_SECTION lpCriticalSection
);
应用中最好将其封装其来使用方便。。需要注意的是,对于互斥Lock,必须防止死锁,Lock后记得UnLock,和内存管理道理一样new出来的东西一定要释放,不一样的是内存可以最后释放,但Lock不行,你必须使用完后立刻释放,因为其他线程可能都在等待处理。
还有就是Lock后的处理尽量简单,因为处理耗时过长,其他操作会引起堵塞。对于这种情况。下次再详细讲