理解信号量时遇到很多麻烦

时间:2014-04-14 21:41:54

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

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

  1. Semaphore(int,int)中两个参数的意义/含义是什么?
  2. 有人可以解释为什么我得到输出BBAAABBC然后它结束了吗?
  3. 总的来说,当我更改代码并观察输出时,我真的很难看到模式。

        #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 个答案:

答案 0 :(得分:1)

  

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

信号量有两种主要用途。

资源有限

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

多个事件

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

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

线程完成工作后,他再次开始等待信号量。如果有任何剩余事件(因为发出信号的事件数超过可用线程数),线程将立即开始处理下一个包。否则线程将再次入睡,等待新事件。