You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Visual C++中如何实现两个线程独立并发运行?

Fixing Concurrent Add/Subtract Threads with Independent Execution

Alright, let's get your threads running independently instead of serially. The root issue in your original code is that you're holding the semaphore while the thread sleeps—this blocks the other thread entirely until the sleeping thread releases the lock. We need to restructure the code so that only the critical operations (modifying the shared integer and writing to the console) are protected, not the sleep period.

Here's the revised code with explanations of the key changes:

using namespace System;
using namespace System::Threading;

public ref class RunStack {
private:
    static Semaphore^ stackSemaphor;
    static int itemStack = 10;
    // Use a single shared Random instance to avoid duplicate random sequences
    static Random^ sharedRand = gcnew Random();

public:
    static void addItem() {
        while (true) {
            // Generate sleep time and wait BEFORE acquiring the lock
            int pause = sharedRand->Next(1, 10) * 1000;
            Thread::Sleep(pause);

            // Only lock for the critical section: modifying the shared value and console output
            stackSemaphor->WaitOne();
            try {
                itemStack++;
                Console::CursorLeft = 3;
                Console::CursorTop = 3;
                Console::WriteLine("Amount in stack: " + itemStack);
            }
            finally {
                // Ensure we always release the semaphore even if something goes wrong
                stackSemaphor->Release();
            }
        }
    }

public:
    static void subItem() {
        while (true) {
            // Sleep first without holding the lock
            int pause = sharedRand->Next(1, 10) * 1000;
            Thread::Sleep(pause);

            stackSemaphor->WaitOne();
            try {
                itemStack--;
                Console::CursorLeft = 3;
                Console::CursorTop = 3;
                Console::WriteLine("Amount in stack: " + itemStack);
            }
            finally {
                stackSemaphor->Release();
            }
        }
    }

    void Main() {
        stackSemaphor = gcnew Semaphore(1, 1);
        Thread^ thread1 = gcnew Thread(gcnew ThreadStart(addItem));
        thread1->Priority = ThreadPriority::Normal;
        thread1->Start();

        Thread^ thread2 = gcnew Thread(gcnew ThreadStart(subItem));
        thread2->Priority = ThreadPriority::Normal;
        thread2->Start();
    }
};

int main(array<System::String ^> ^args) {
    Console::Title = "ItemStack";
    RunStack^ runIt = gcnew RunStack();
    runIt->Main();
    return 0;
}

Key Changes Explained:

  • Moved Sleep Outside the Critical Section
    By sleeping before acquiring the semaphore, the thread doesn't hold the lock while it's waiting. This lets the other thread execute its critical section multiple times if the first thread is asleep.

  • Shared Random Instance
    Creating a Random instance per thread can lead to identical random sequences if threads start at nearly the same time. Using a single shared instance ensures more varied sleep times. (Note: Random::Next is thread-safe for basic usage here, but you could add a lock around it if you need strict thread safety.)

  • Try/Finally Block for Semaphore Release
    This guarantees the semaphore is always released, even if an unexpected error occurs during the critical section. It's a best practice to prevent deadlocks.

Now when you run the code, you'll see that one thread can perform multiple add or subtract operations while the other is sleeping—exactly the independent execution you wanted.

内容的提问来源于stack exchange,提问作者PQuix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:39:07