写了个操作硬件端口的程序,会被5个进程调用,但硬件端口在同一时刻只能被一个进程独占调用。
最简单的方法是通过操作系统提供的互斥对象:
// 获取互斥标志
int WaitProcessIdle()
{
while(1){
_processHd = CreateMutex(NULL, false, "LxjOpPort");
if( _processHd && GetLastError()==ERROR_ALREADY_EXISTS ){ // 如果被其他进程占住了,就等一会再来
printf("CreateMutex ERROR_ALREADY_EXISTS\n");
if( _processHd!=NULL ){
CloseHandle(_processHd);
}
::Sleep(1000); // 等1秒钟
continue;
}
else if( _processHd!=NULL ){
printf("CreateMutex OK.\n"); // 获取到了
break;
}
else {
printf("CreateMutex Fail.\n");
break;
}
}
return(0);
}
程序运行的开始调用:
int ret = WaitProcessIdle();
printf("正在执行任务...\n");
开始执行端口操作,大概20秒钟
..程序退出的时候关闭互斥对象。
如果只有2个进程争抢端口,这个机制运作良好,A进程执行的时候,另外B进程等候,A进程执行完毕B进程马上执行。
当5个进程同时争抢端口,而且频繁调用时,将会出现某个进程等候时间很长的情况,因为在等候时Sleep(1000),随时可能被前面的人抢走。
就像5个人不排队,在哄抢一件东西,能否抢到全凭运气。我们需要一种先来后到的排队机制,怎么做呢?
代码说话,看看我这个改进版本:
const int MAX_MUTEX = 5;
char * _mutexName[MAX_MUTEX] = {"lxjop0", "lxjop1", "lxjop2", "lxjop3", "lxjop4"}; // 5个互斥对象的名字
int WaitProcessIdleEx() // 改进版本
{
int i = MAX_MUTEX-1; // 总是从最尾部开始排队
while(1){
HANDLE hd = CreateMutex(NULL, false, _mutexName[i]);
if( hd && GetLastError()==ERROR_ALREADY_EXISTS ){ // 如果当前位置有人,就老实等着
printf("CreateMutex ERROR_ALREADY_EXISTS [%s]\n", _mutexName[i]);
CloseHandle(hd);
::Sleep(1000); // 等1秒钟
continue;
}
else if( hd!=NULL ){ // 排上了
if( i<=0 ){ // 如果已经是最前面了,就占用这个资源,做该做的事情
_processHd = hd;
printf("CreateMutex OK.\n");
break;
}
i--; // 往前排一位
if( _processHd ){
CloseHandle(_processHd); // 把刚才的位置腾出来
}
_processHd = hd;
}
else {
printf("CreateMutex Fail.\n");
break;
}
}
return(i);
}
调用的时候差不多:
int ret = WaitProcessIdleEx();
printf("正在执行任务...\n");
开始执行端口操作,大概20秒钟
..程序退出的时候关闭互斥对象。
这种办法还是很巧妙的,适合对多个进程排队以操作唯一的资源。