【问题标题】:What is the use of lmaxcount argument in CreateSemaphore() API?CreateSemaphore() API 中 lmaxcount 参数的用途是什么?
【发布时间】:2013-09-05 07:26:46
【问题描述】:

我正在学习 Windows 操作系统,并且正在编写标准的消费者生产者问题。我有一个用于资源计数的信号量和一个用于同步的 Mutex。我在 CreateSemaphore() 中传递了 max count 50 的值,所以它不应该允许生产者创建超过 50 个资源。但是当我运行代码时,它远不止于此。我是否错误地理解了 max count 参数的使用? 我也在粘贴代码。请帮我解决这个问题。

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

DWORD WINAPI consumerThread(LPVOID args);
DWORD WINAPI producerThread(LPVOID args);

int shared;
HANDLE hMutex;
HANDLE hSemaphore;
HANDLE hConsumer;
HANDLE hProducer;
DWORD dwConsumerId,dwProducerId;

#define MAX_COUNT 50
#define MIN_COUNT 0
int main()
{
    if(!(hMutex=CreateMutex(NULL,0,NULL)))
    {
        puts("Error:: unable to create Mutex!!");
        ExitProcess(GetLastError());
    }
    if(!(hSemaphore=CreateSemaphore(NULL,MIN_COUNT,MAX_COUNT,NULL)))
    {
        puts("Error:: unable to create Semaphore object!!");
        ExitProcess(GetLastError());
    }
    if(!(hConsumer=CreateThread(NULL,0,consumerThread,NULL,0,&dwConsumerId)))
    {
        puts("Error:: unable to create consumer Thread!!");
        ExitProcess(GetLastError());
    }
    if(!(hProducer=CreateThread(NULL,0,producerThread,NULL,0,&dwProducerId)))
    {
        puts("Error:: unable to create producer Thread!!");
        ExitProcess(GetLastError());
    }
    WaitForSingleObject(hConsumer,INFINITE);
    WaitForSingleObject(hProducer,INFINITE);
    CloseHandle(hMutex);
    CloseHandle(hSemaphore);
    CloseHandle(hConsumer);
    CloseHandle(hProducer);
    return 0;
}

DWORD WINAPI consumerThread(LPVOID args)
{

    while(1)
    {
        WaitForSingleObject(hSemaphore,INFINITE);
        WaitForSingleObject(hMutex,INFINITE);
        shared--;
        printf("Consumer  = %d\n",shared);
        ReleaseMutex(hMutex);
        //Sleep(1000);
    }
}

DWORD WINAPI producerThread(LPVOID args)
{
    if(!SetThreadPriority(hProducer,THREAD_PRIORITY_HIGHEST))
    {
        printf("Error:: Unable to set the thread priority level!!\n");
        ExitProcess(GetLastError());
    }
    while(1)
    {
        WaitForSingleObject(hMutex,INFINITE);
        shared++;
        printf("Producer =%d\n",shared);
        ReleaseMutex(hMutex);
            ReleaseSemaphore(hSemaphore,1,NULL);


    }
}

【问题讨论】:

  • 您只是使用了错误的信号量。它仅在您调用 WFSO 并达到零时阻塞。没有“最小计数”。您必须将其初始化为 MAX_COUNT 并在生产者中调用 WFSO。并在消费者中发布。注意死锁。
  • 我明白了你的意思,但是 lmaxcout 参数有什么用呢?为什么他们提供了两个参数,初始值和最大计数?你告诉我使用它的方式,我只需要一个参数,用某个值初始化它并调用 WFSO ??
  • 只要不检查ReleaseSemaphore()的返回值就没有意义。这将告诉您何时您的代码有错误并且过于频繁地发布。不是你想跳过的东西。
  • @IgorTandetnik in CreateEvent bInitialState 允许我在有信号或无信号状态下创建一个新对象,在 CreateMutex bInitalOwner 中允许我获得互斥锁的所有权。所以所有这些都是有道理的。 lmaxcount 有什么用,如果它没有阻塞正在进一步增加这个限制的线程?
  • “信号量对象的最大计数。此值必须大于零”这是在 MSDN 文档中为 lmaxcount 参数编写的。现在我想从中得到什么?

标签: c windows visual-studio visual-c++


【解决方案1】:

@Hans Passant 和 @Igor Tandetnik 在 cmets 中回答了这个问题。要点是,如果您尝试将 semaphore 的值增加到超出 lmaxcount 参数中指定的值,ReleaseSemaphore() API 将失败,而不是阻塞调用线程。所以你应该检查它的返回值,因为我没有这样做并陷入困境。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-28
    相关资源
    最近更新 更多