gpt4 book ai didi

c# - 无锁线程安全队列——需要建议

转载 作者:行者123 更新时间:2023-11-30 19:34:11 26 4
gpt4 key购买 nike

我需要设计一个线程安全的记录器。我的记录器必须有一个 Log() 方法,它只是将要记录的文本排入队列。此外,记录器必须是无锁的——以便其他线程可以在不锁定记录器的情况下记录消息。我需要设计一个必须等​​待的工作线程对于某些同步事件,然后使用标准 .NET 日志记录(这不是线程安全的)记录队列中的所有消息。所以我感兴趣的是工作线程的同步 - 和日志功能。下面是我设计的类的草图。我想我必须在这里使用 Monitor.Wait/Pulse 或任何其他方式来暂停和恢复工作线程。我不想在没有记录器工作时花费 CPU 周期。

让我换一种说法 - 我想设计一个记录器,它不会阻塞使用它的调用线程。我有一个高性能系统——这是一个要求。

class MyLogger
{
// This is a lockfree queue - threads can directly enqueue and dequeue
private LockFreeQueue<String> _logQueue;
// worker thread
Thread _workerThread;
bool _IsRunning = true;

// this function is used by other threads to queue log messages
public void Log(String text)
{
_logQueue.Enqueue(text);
}

// this is worker thread function
private void ThreadRoutine()
{
while(IsRunning)
{
// do something here
}
}
}

最佳答案

“无锁”并不意味着线程不会互相阻塞。这意味着它们通过非常有效但也非常棘手的机制相互阻止。仅在非常高性能的场景中需要,即使是专家也会出错(很多)。

最佳建议:忘记“无锁”,只使用“线程安全”队列。

我会推荐 this page 中的“阻塞队列” .

在类本身中包含 ThreadRoutine(消费者)是一个选择问题。

对于你问题的第二部分,这取决于“一些同步事件”到底是什么。如果您打算使用方法调用,那么让它启动一个一次性线程。如果您想在信号量上等待,不要使用 Monitor 和 Pulse。他们在这里不可靠。使用 AutoResetEvent/ManualResetEvent。
如何显示取决于您希望如何使用它。

你的基本成分应该是这样的:

class Logger
{
private AutoResetEvent _waitEvent = new AutoResetEvent(false);
private object _locker = new object();
private bool _isRunning = true;

public void Log(string msg)
{
lock(_locker) { _queue.Enqueue(msg); }
}

public void FlushQueue()
{
_waitEvent.Set();
}

private void WorkerProc(object state)
{
while (_isRunning)
{
_waitEvent.WaitOne();
// process queue,
// ***
while(true)
{
string s = null;
lock(_locker)
{
if (_queue.IsEmpty)
break;
s = _queue.Dequeu();
}
if (s != null)
// process s
}
}
}
}

部分讨论似乎是在处理Queue时要做什么(标记为***)。您可以锁定队列并处理所有项目,在此期间将阻止(更长时间)添加新条目,或者逐个锁定和检索条目并且每次只锁定(非常)短时间。我已经添加了最后一个场景。

总结:您需要的不是无锁解决方案,而是无 block 解决方案。 Block-Free 不存在,您将不得不接受尽可能少的阻塞。 mys 示例的最后一次迭代(不完整)显示了如何仅锁定入队和出队调用。我认为这将足够快。

关于c# - 无锁线程安全队列——需要建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2048785/

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