信号量值

时间:2010-04-05 16:32:43

标签: multithreading winapi semaphore

我有一个关于使用信号量的问题

HANDLE WINAPI CreateSemaphore(...);

无论如何我能获得信号量的当前值吗?

5 个答案:

答案 0 :(得分:7)

此处使用Native {Api的解决方案,由http://undocumented.ntinternals.net/记录。 我省略了一些东西,因为这会使代码更长。当您理解本机API的语法时,代码很简单。例如(几乎)所有本机api函数,这些由ntdll导出并且没有由microsoft记录,返回NTSTATUS,并且不使用函数simliar来获取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,例如,如果您可以使用此函数接收sempahore的名称,则此参数可以在第一次调用后使用不正确的SemaphoreInformationLength保存需要的缓冲区大小。

够了!代码:))

#include <windows.h>
#include <stdio.h>

typedef LONG NTSTATUS;

typedef NTSTATUS (NTAPI *_NtQuerySemaphore)(
    HANDLE SemaphoreHandle, 
    DWORD SemaphoreInformationClass, /* Would be SEMAPHORE_INFORMATION_CLASS */
    PVOID SemaphoreInformation,      /* but this is to much to dump here     */
    ULONG SemaphoreInformationLength, 
    PULONG ReturnLength OPTIONAL
); 

typedef struct _SEMAPHORE_BASIC_INFORMATION {   
    ULONG CurrentCount; 
    ULONG MaximumCount;
} SEMAPHORE_BASIC_INFORMATION;


int main (int argc, char *argv[])
{
    _NtQuerySemaphore NtQuerySemaphore;
    HANDLE Semaphore;
    SEMAPHORE_BASIC_INFORMATION BasicInfo;
    NTSTATUS Status;


    Semaphore = CreateSemaphore (NULL, 50, 100, "Test");

    NtQuerySemaphore = (_NtQuerySemaphore)GetProcAddress (GetModuleHandle ("ntdll.dll"), "NtQuerySemaphore");

    if (NtQuerySemaphore)
    {

        Status = NtQuerySemaphore (Semaphore, 0 /*SemaphoreBasicInformation*/, 
            &BasicInfo, sizeof (SEMAPHORE_BASIC_INFORMATION), NULL);

        if (Status == ERROR_SUCCESS)
        {       
            printf ("CurrentCount: %lu", BasicInfo.CurrentCount);
        }
    }

    CloseHandle (Semaphore);
}

最后一点,请注意,microsoft可以删除或更改此功能的工作方式。

干杯恶鬼

答案 1 :(得分:5)

不,那是故意的。即使您可以获得“当前”值,在您可以对其执行任何操作之前,该值可能已经发生了很大变化。对它做任何事情的唯一方法是以原子方式获取和设置值 - 例如,等待信号量空闲将其设置为“拥有”(通过该段代码)同样的操作。

答案 2 :(得分:1)

答案 3 :(得分:0)

您可以随时使用:

//ReleaseSemaphore(Last Parameter- Previous Count)

如果您希望主线程等到所有线程完成执行。

//CreateEvent
//Assign threads
//ResetEvent
//WaitForSingleObject( hEvent, INFINITE) ;

//When you call the threads function and after releasing Semaphore.
//Check for the previousCount, if it is equal to MAX_SEMAPHORES-1, SetEvent()...

希望它会有所帮助。

答案 4 :(得分:-1)

我想你需要打电话

DWORD WINAPI WaitForSingleObject

将第二个参数设置为0(请求立即结果)。

并根据结果采取行动。

我希望这会对你有所帮助, 杰罗姆瓦格纳