gpt4 book ai didi

.net - 如何使Stack.Pop线程安全

转载 作者:行者123 更新时间:2023-12-03 13:15:45 25 4
gpt4 key购买 nike

我正在使用发布在in this question上的BlockingQueue代码,但意识到我的程序如何运行,我需要使用堆栈而不是队列。我将其转换为使用Stack,并根据需要将其重命名。为了提高性能,我删除了Push中的锁定,因为我的生产者代码是单线程的。

我的问题是如何才能在(现在)线程安全堆栈上工作的线程知道何时为空。即使我在Count周围添加了另一个线程安全包装器,如Push和Pop一样锁定了底层集合,我仍然遇到竞争情况,即访问Count,然后Pop并不是原子的。

当我看到它们时可能的解决方案(首选,我是否缺少能更好地工作的解决方案?):

  • 使用者线程捕获Pop()引发的InvalidOperationException。
  • 当_stack-> Count == 0时,
  • Pop()返回nullptr,但是C++-CLI没有default()运算符ala C#。
  • Pop()返回一个 bool 值,并使用输出参数返回弹出的元素。

  • 这是我现在正在使用的代码:
    generic <typename T>
    public ref class ThreadSafeStack
    {
    public:
    ThreadSafeStack()
    {
    _stack = gcnew Collections::Generic::Stack<T>();
    }

    public:
    void Push(T element)
    {
    _stack->Push(element);
    }

    T Pop(void)
    {
    System::Threading::Monitor::Enter(_stack);
    try {
    return _stack->Pop();
    }
    finally {
    System::Threading::Monitor::Exit(_stack);
    }
    }

    public:
    property int Count {
    int get(void)
    {
    System::Threading::Monitor::Enter(_stack);
    try {
    return _stack->Count;
    }
    finally {
    System::Threading::Monitor::Exit(_stack);
    }
    }
    }

    private:
    Collections::Generic::Stack<T> ^_stack;
    };

    最佳答案

    就个人而言,我将使用您的选项3.,但重命名此TryPop()。

    这将使其行为更像框架的 ConcurrentQueue<T>.TryDequeue (在.NET 4中)。

    编辑:

    我会这样声明:

    public:
    bool TryPop([Out] T% result);

    在实现中,您只需在方法主体中设置T值即可。

    关于.net - 如何使Stack.Pop线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2448928/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com