【问题标题】:Having a lot of trouble understanding Semaphores理解信号量有很多麻烦
【发布时间】:2014-04-14 21:41:54
【问题描述】:

这是一个基本代码,我的目标是打印出 AAABBCAAABBC....等等。

  1. Semaphore(int, int) 中两个参数的意义/意义是什么?
  2. 谁能解释为什么我得到输出 BBAAABBC 然后它就结束了?

总的来说,当我对代码进行更改并观察输出时,我真的很难看到一种模式。

    #include "stdafx.h"

    using namespace System;
    using namespace System::Threading;

    ref class PrintTasks
    {
    private:
        static Semaphore ^canPrintA = gcnew Semaphore(0,3);
        static Semaphore ^canPrintB = gcnew Semaphore(2,2);
        //static Semaphore ^canPrintC = gcnew Semaphore(0,1);
        static Semaphore ^Idle = gcnew Semaphore(0,3);


    public: static bool runFlag = true;

    public:
        void PrintA(Object^ name) {
            while (runFlag) {
                canPrintA->WaitOne();
                Console::Write("{0}\n", "A");
                Idle->Release();
            }
        }

        void PrintB(Object^ name) {
            while (runFlag) {
                canPrintB->WaitOne();
                Console::Write("{0}\n", "B");
                Idle->Release();
            }
        }

        void PrintC(Object^ name) {
            while (runFlag) {
                Idle->WaitOne();
                Idle->WaitOne();
                                    Console::Write("{0}\n", "C");
                canPrintA->Release(3);
                Idle->WaitOne();
                Idle->WaitOne();
                Idle->WaitOne();
                canPrintB->Release(2);
                //Console::Write("{0}\n", "C");



            }
        }

    };

    int main(array<System::String ^> ^args)
    {

        PrintTasks ^tasks = gcnew PrintTasks();

        // First Method
        Thread ^thread1 = gcnew Thread ( gcnew ParameterizedThreadStart( tasks, &PrintTasks::PrintA ) );
        Thread ^thread2 = gcnew Thread ( gcnew ParameterizedThreadStart( tasks, &PrintTasks::PrintB ) );
        Thread ^thread3 = gcnew Thread ( gcnew ParameterizedThreadStart( tasks, &PrintTasks::PrintC ) );

        thread1->Start("printA");
        thread2->Start("printB");
        thread3->Start("printC");

        Thread::Sleep(50);

        PrintTasks::runFlag=false;

        thread3->Abort();
        thread2->Abort();
        thread1->Abort();

        return 0;
    }

【问题讨论】:

  • 1) msdn.microsoft.com/en-us/library/… : "初始化 Semaphore 类的新实例,指定并发条目的最大数量并可选择保留一些条目。"
  • 好的...但是将其设置为 Semaphore(2,2) 有什么作用?
  • 您不明白还是根本没有阅读?如果 1:你知道信号量是用来做什么的吗?
  • 你不能使用一个信号量来订购 3 个线程,它需要三个线程。允许一个线程释放另一个线程。您通常会改用三个 AutoResetEvents。整个方法一开始是错误的,如果您希望 ABC 按顺序出现,那么只需使用 one 打印 A、B、然后 C 的线程。让更多线程等待是没有意义的轮到他们了,这既浪费又慢。
  • 我读了一遍,但还是一头雾水。

标签: .net multithreading c++-cli semaphore


【解决方案1】:

Semaphore(int,int) 中两个参数的意义/意义是什么?

信号量主要有两种用途。

资源有限

可以使用信号量来限制对有限资源的访问。为此,请将最大计数器设置为所需的限制,并将初始计数设置为零。每个分配资源的线程必须先WaitForSingleObject() 才能获得一个空闲的信号量“槽”。如果没有更多空闲槽,等待将阻塞,直到一个线程释放信号量句柄,为下一个等待线程腾出空间。对于这个用例,信号量的使用可以最好地描述为 multi-mutex

多个事件

另一个典型用例是发出多个事件发生的信号的能力,例如使用线程池。使用 MAXINT 或其他一些足够高的值初始化信号量最大值和当前计数。该值本身并不重要(越高越好),它必须足够高以涵盖所有可能的情况。然后让所有工作线程等待您的信号量。由于还没有空闲句柄,所有工作线程都会阻塞等待。

现在,每当有一些任务进入本应由我们的线程池处理时,该事件就会通过ReleaseSemaphore() 释放一个或多个句柄来发出信号,从而准确地从池中唤醒该数量的线程。这些线程现在将执行他们想要的工作,例如从某处拾取和处理工作任务。

一旦线程完成他的工作,他就会再次开始等待信号量。如果还有剩余的事件(因为信号事件的数量超过了可用线程的数量),线程将立即开始处理下一个包。否则线程将再次进入休眠状态,等待新事件。

【讨论】:

  • 看来第二次使用是我想要使用的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
相关资源
最近更新 更多