Multithreading Win32 Uderstanding信号量

Multithreading Win32 Uderstanding信号量,multithreading,winapi,semaphore,Multithreading,Winapi,Semaphore,我不熟悉Win32中的多线程。我有一个关于信号量的赋值。但我不能理解这一点 假设我们有20个任务(每个任务与其他任务相同)。我们使用信号量,然后有两种情况: 首先,应该有20个子线程,以便每个线程处理1个任务 或: 其次,将有n个子线程。当一个线程完成一个任务时,它会处理另一个任务吗 我指出的第二个问题是,我在Win32(API)中找不到任何信号量示例,但在MSDN中找到了Consonle 您能否帮助我完成“20任务”,并告诉我在WinAPI应用程序中编写信号量的说明(我应该将CreateSem

我不熟悉Win32中的多线程。我有一个关于信号量的赋值。但我不能理解这一点

假设我们有20个任务(每个任务与其他任务相同)。我们使用信号量,然后有两种情况:

首先,应该有20个子线程,以便每个线程处理1个任务

或:

其次,将有n个子线程。当一个线程完成一个任务时,它会处理另一个任务吗

我指出的第二个问题是,我在Win32(API)中找不到任何信号量示例,但在MSDN中找到了Consonle

您能否帮助我完成“20任务”,并告诉我在WinAPI应用程序中编写信号量的说明(我应该将CreateSemaphore()函数放在哪里


您的建议将不胜感激。

您可以为每个任务启动一个线程,这是一种常见的方法,或者您可以使用“线程池”来重用线程。这取决于你。在这两种情况下,您可以使用也可以不使用信号量,区别仅在于如何启动多个线程

现在,关于将CreateSemaphore()函数放置在何处的问题,您应该在开始任何其他线程之前调用它。原因是这些线程需要访问信号量,但如果信号量还不存在,它们就无法访问。当然,您可以将它传递给其他线程,但这同样会给您带来如何在没有任何竞争条件的情况下安全地传递它的问题,这是信号量和其他同步原语要避免的。换句话说,你只会制造一个鸡和蛋的问题,从而使事情复杂化


请注意,如果这对您没有任何帮助,您可能应该提供更多信息。目标是什么?到目前为止你自己都做了些什么?您在这里读到的任何相关问题,但没有完全给出问题的答案吗?

好吧,如果您限制只使用信号量,那么您可以使用两个信号量来创建一个无限生产者-消费者队列类,您可以用它来实现线程池

任务对象需要一个“SimpleQueue”类。我假设你已经有了一个,可以很容易地建立一个或任何东西

在“ProducerConsumerQueue”类的构造函数中(或在main()中,或在返回*ProducerConsumerQueue结构的某个工厂函数中,无论您的语言如何),创建一个SimpleClass和两个信号量。“QueueCount”信号量(使用计数0初始化)和“QueueAccess”信号量(使用计数1初始化)

将“push(*task)”和“*task pop()”方法/成员函数/方法添加到ProducerConsumerQueue:

在“push”中,首先在QueueAccess上调用“WaitForSingleObject()”API,然后将*任务推送到SimpleQueue上,然后在QueueAccess上释放信号量()API。这将以线程安全的方式推送*任务。然后在QueueCount上释放信号量()-这将向所有等待的线程发出信号

在pop()中,首先对QueueCount调用'WaitForSingleObject()'API-这确保任何调用使用者线程都必须等待,直到队列中有*任务。然后在QueueAccess上调用'WaitForSingleObject()'API,然后从SimpleQueue中弹出任务,然后在QueueAccess上释放Semaphore()API并返回任务-此线程安全地将*任务出列

创建ProducerConsumerQueue后,创建一些线程来运行任务。在CreateThread()中,传递与“辅助”*void参数相同的*ProducerConsumerQueue

在thread函数中,将*void强制转换回*ProducerConsumerQueue,然后一直循环,调用pop(),然后运行返回的任务

好的,你的线程池现在已经准备好做一些事情了。如果要运行20个任务,请在循环中创建它们,并将它们推送到ProducerConsumerQueue上。然后线程将全部运行它们

您可以在池中创建任意数量的线程(在合理范围内)。对于CPU密集型任务,线程数与内核数相同是合理的。如果任务进行阻塞调用,您可能希望创建更多线程以获得最快的总体吞吐量


一个有用的增强是在接收到每个任务后检查线程函数循环中的“null”,如果为null,则清除退出线程,从而终止它。这使得线程可以通过将空值排队来轻松终止,从而更容易关闭线程池(如果需要),并在运行时控制线程池中的线程数。

我应该将CreateSemaphore()放在WinMain或WM_CREATE中吗?无论何时何地都可以!如果我是你,我会暂时忘记windows,而使用一个简单的控制台应用程序来保持简单。