我需要设计一个线程安全记录。我的记录器必须有一个简单的队列中记录文本日志()方法。另外一个记录器必须是无锁 - 让其他线程可以登录的消息不锁定记录。我需要设计一个工作线程必须等待 对于一些同步事件,然后登录使用标准的.NET日志队列中的所有邮件(不是线程安全的)。所以,我所感兴趣的是工作线程的同步 - 和日志功能。下面是我设计的类的草图。我想我必须在这里使用Monitor.Wait /脉冲或其他任何方式挂起和恢复工作线程。我不;吨要花费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
 }
}    
}
有帮助吗?

解决方案

“无锁的”并不意味着线程将不会彼此阻塞。这意味着,他们通过非常高效,而且非常棘手的机制阻止对方。只需要非常高的性能场景和连专家搞错了(很多)。

最好的建议:忘记“无锁”,只是用一个“线程安全”的队列

我建议从当前页

和它的选择,包括在类本身ThreadRoutine(消费者)的问题。

要你问题的第二部分,要看是什么“的一些同步事件”到底是。如果你要使用一个方法调用,然后让那个启动一锤子线。如果你想等待一个信号灯比的的使用监控和脉搏。他们是不可靠的在这里。使用的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
            }
        } 
    }
}

讨论的部分似乎是处理所述队列(标记***)时该怎么办。您可以锁定队列和过程中的所有项目,在此期间,新条目的添加将被阻止(长),或锁定,并通过唯一锁(非常)不久每次检索条目之一。我已经ADDE是最后一个场景。

摘要:你不想要一个无锁的解决方案,但一个块免费的。块免费不存在,你将不得不解决的东西,块尽可能少。 MYS样品的最后一次迭代(不完全统计)显示如何锁定只围绕加入和离开队列调用。我认为,这将是速度不够快。

其他提示

向你展示了你的分析器,您遇到通过使用简单lock声明一个大的开销?无锁编程是很难得到正确的,如果你真的需要它,我会建议服用从可靠的来源存在的东西。

这并不难,如果你有原子操作,使这个无锁的。以一个单向链表;你只需要在指针。

日志功能:结果 1.准备本地日志项(节点与测井组)。结果 2.设置本地节点的下一个指针为即可。结果 3. ATOMIC:比较与本地节点的下一个,如果相等,则更换的与本地节点的地址结果。 4.如果操作失败,则重复从步骤2,否则,产品可在“队列”。

工人:结果 1.复制的本地。结果 2.的原子比较的当地一个,如果相等,则替换的使用NULL结果。 3.如果操作失败,请重复步骤1点击 4.如果它成功了,处理的物品;其是现在本地和移出“排队”的。

scroll top