信号量值
我有一个关于使用信号量的问题
HANDLE WINAPI CreateSemaphore(...);
我是否可以获得信号量的当前值?
I have a question regarding using Semaphores
HANDLE WINAPI CreateSemaphore(...);
Is there anyway I can get the current value of the semaphore?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不,这是故意的。即使您可以获得“当前”值,在您可以对其执行任何操作之前,该值很可能已经发生变化。使用它做任何事情的唯一方法是原子地获取和设置值 - 例如,等待信号量空闲并将其设置为“拥有”(由该代码段)相同的操作。
No, and that's intentional. Even if you could get the "current" value, that value might very well have changed before you could do anything with it. The only way to do anything with it is to get and set the value atomically -- e.g., wait for the semaphore to be free and set it to "owned" (by that piece of code) in the same operation.
可以通过无证的NtQuerySemaphore解决
参见:
http://forums.msdn.microsoft.com/en-US/vcgeneral/thread/c44f0e63-b20f-4895-9dc3-eb2034de2aa4
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Semaphore/NtQuerySemaphore.html
Can be solved by undocumented NtQuerySemaphore
See:
http://forums.msdn.microsoft.com/en-US/vcgeneral/thread/c44f0e63-b20f-4895-9dc3-eb2034de2aa4
http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Semaphore/NtQuerySemaphore.html
您始终可以使用:
如果您希望主线程等待所有线程完成其执行。
希望它会有所帮助。
You can always use:
If you want your Main thread to wait till all threads complete its execution.
Hope it would help.
我认为您需要
将第二个参数设置为 0(请求立即结果)进行调用。
并根据结果采取行动。
我希望这对你有帮助
杰罗姆·瓦格纳
I think you need to call
with a second argument set to 0 (immediate result requested).
and take actions depending on the result.
I hope this will help you,
Jerom Wagner
这里是使用 Native Api 的解决方案,由 http://undocumented.ntinternals.net/ 记录。
我省略了一些事情,因为这些会使代码变得更长。当您了解本机 api 的语法时,代码很简单。例如(几乎)所有本机 api 函数,这些由 ntdll 导出且微软没有详细记录的函数,返回 NTSTATUS,并且不使用类似的函数来获取 Set/GetLastError ()。如果 NtQuerySemaphore 失败(Status != STATUS_SUCCESS),您可能需要在此处查找错误代码:http ://source.winehq.org/source/include/ntstatus.h。
好吧,让我们开始看代码,它非常简单,首先定义一些可以从 ntinernals.net 获得的结构。然后获取ntdll.dll中NtQuerySemaphore的地址。您不需要使用LoadLibrary,因为每个进程都加载了ntdll.dll。
NtQuerySemaphore 也很简单,第一个参数是信号量的句柄,第二个参数是要检索的信息类(在我们的例子中 SemaphoreBasicInformation = 0x0)。
第三个参数是指向结构的指针,用于查看信息。第四个参数是结构的大小。第五个是 ReturnLength,例如,如果您可以使用此函数接收信号量的名称,则此参数可以在第一次使用不正确的 SemaphoreInformationLength 调用后保存所需的缓冲区大小。
足够的!代码:)
最后一件事,请注意,微软可以删除或更改此功能的工作方式。
干杯邪恶派
Here the solution using Native Api, documented by http://undocumented.ntinternals.net/.
I ommited a few thing because these would make the code even longer. The code is easy, when you understand the syntax of the native api. For example (nearly) all native api function, these exported by ntdll and not documented well by microsoft, return NTSTATUS, and dont use a functions simliar to get Set/GetLastError (). If NtQuerySemaphore fails (Status != STATUS_SUCCESS) you might want to look up the error code here: http://source.winehq.org/source/include/ntstatus.h.
Okay lets get to the code, its pretty straight forward, first defining some structs you can get from ntinernals.net. Then getting the address of NtQuerySemaphore in the ntdll.dll. You dont need to use LoadLibrary, because every process has ntdll.dll loaded.
NtQuerySemaphore is easy too, first parameter is the handle to the semaphore, second the information class you want to retrive (in our case SemaphoreBasicInformation = 0x0).
Thee third parameter is an pointer to an struct, wich revieces the informations. Fourth paramwter is the sizeof the struct. Fifth would be the the ReturnLength, for example if you could recieve the name of the sempahore with this function, this parameter could hold the need buffer size after the first call with an incorrect SemaphoreInformationLength.
Enough! Code :)
One last thing, be warned, microsoft could remove or change the way this function works.
Cheers evilpie