对 thread.semaphore 中的一段源码有疑惑,请指教

By terrorist at 15 天前 • 0人收藏 • 159人看过
this.handle  =  CreateSemaphore(null,initCount,max,semaphoreName); 
if(! this.handle ) {
	if( targ1== "string") {	
		this.handle  =  OpenSemaphore( 0x1F0003/*_EVENT_ALL_ACCESS*/,false ,semaphoreName);
		if( this.handle ) this.conflict = "信号量已存在";
	}
}

为什么 CreateSemaphore 失败后还要 OpenSemaphore ?

8 个回复 | 最后更新于 21 天前
14 天前   #1

CreateSemaphore失败的原因有许多种,其中一种是同名的semaphoreName信号量已存在, OpenSemaphore 就是检验是不是这个原因

14 天前   #2

根据 https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createsemaphorea


CreateSemaphore  的返回值有三种情况:


1 如果函数成功,返回值是一个指向semaphore对象的句柄。

2 如果在调用该函数之前,命名的信号灯对象已经存在,该函数将返回一个指向现有对象的句柄,并且GetLastError返回ERROR_ALREADY_EXISTS

3 如果该函数失败,返回值为NULL。要获得扩展的错误信息,请调用GetLastError。


同名的semaphoreName信号量已存在也不会返回 NULL

14 天前   #3

回复#1 @popy32 :

他这是在等着你这样回答,然后再自信地反驳。


14 天前   #4

回复#2 @terrorist :


既然已经有了那么自信的答案,把文章题目改一下吧 :《我发现了标准库一段代码的存在的 BUG,我已经找到了证据》。

14 天前   #5
if( !max || max <=0 ) error("@参数2 最大计数值必须大于0");

if(initCount <= 0) error("@参数3 初始计数值必须大于0");
elseif(initCount > max) error("@参数3 初始计数值不能大于最大计数值");
elseif(initCount === null) initCount = max;

if(targ1 == "string"){
	// 尝试打开
	this.handle = OpenSemaphore(0x1F0003/*_EVENT_ALL_ACCESS*/, false, semaphoreName);
	if(this.handle){
		this.conflict = "信号量已存在"
	}
	else {
		this.handle = CreateSemaphore(null, initCount, max, semaphoreName); 
		if(this.handle){
		    this.handle = OpenSemaphore(0x1F0003/*_EVENT_ALL_ACCESS*/, false, semaphoreName);
		}
	}
}
elseif(targ1 === null){
	this.handle = CreateSemaphore(null, initCount, max, null);
}

if(!this.handle) return null, ..lasterr()

..table.gc( this,"close" );

这是修改版

14 天前   #6

回复#5 @terrorist :


你的改动会让原来运行没有问题的程序出现问题。

CreateSemaphore 如果成功返回句柄,然后你再去 OpenSemaphore 打开一次句柄 —— 这是多余的,参考你自己复制过来的文档。

即使你真要这样做,你也应当先把 上一个句柄关闭。



14 天前   #7

原来我写的代码在CreateSemaphore 之前已经调用了 OpenSemaphore 检查

所以那段代码的目的并不是为了用 CreateSemaphore 去检查信号量是不是已经存在。

我之前在使用 CreateMutex 的时候遇到一个问题,同样的代码一直运行正常,但存在极小的概率 OpenMutex,CreateMutex 打开存在的 mutex 都会失败,所以我在这两个 API 都调用失败以后,再加了一次 OpenMutex 尝试,类似的信号量这些都套用了这段代码。

这段代码如果造成了你的困扰 —— 你可以当没看到,不会造成任何问题,也没必要去修改。

14 天前   #8

回复#7 @jacen :

感谢指教

登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
aardio可以快速开发上位机,本站主要记录了学习过程中遇到的问题和解决办法及aardio代码分享

这里主要专注于aardio学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.

AARDIO语言QQ群:70517368
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
C大Aardio论坛:Aar爱好者论坛
本 站 主 站:Stm32cube中文网
Sciter中文在线文档Sciter在线学习文档
赞助商:才仁机械
Loading...