具有变体的生产者-消费者 - 如何与线程信号/等待同步?
在从事一个大型项目时,我意识到我要打很多电话来安排未来的工作。由于它们相当轻量,我认为使用单独的调度程序可能会更好。
ThreadPool.QueueUserWorkItem (() =>
{
Thread.Sleep (5000);
Foo (); // Call is to be executed after sometime
});
因此,我创建了一个单独的调度程序类,它在自己的线程上运行并执行这些事件。我有两个函数可以从单独的线程访问共享队列。我会使用锁,但由于其中一个线程需要睡眠等待,我不确定如何释放锁。
class Scheduler
{
SortedDictionary <DateTime, Action> _queue;
EventWaitHandle _sync;
// Runs on its own thread
void Run ()
{
while (true)
{
// Calculate time till first event
// If queue empty, use pre-defined value
TimeSpan timeDiff = _queue.First().Key - DateTime.Now;
// Execute action if in the next 100ms
if (timeDiff < 100ms)
...
// Wait on event handle for time
else
_sync.WaitOne (timeDiff);
}
}
// Can be called by any thread
void ScheduleEvent (Action action, DataTime time)
{
_queue.Add (time, action);
// Signal thread to wake up and check again
_sync.Set ();
}
}
虽然这在某种程度上面向 C#,但我很高兴听到对此的通用解决方案。谢谢!
While working on a large project I realized I was making a lot of calls to be scheduled in the future. Since these were fairly light-weight, I thought it might be better to use a separate scheduler.
ThreadPool.QueueUserWorkItem (() =>
{
Thread.Sleep (5000);
Foo (); // Call is to be executed after sometime
});
So I created a separate scheduler class that runs on its own thread and executes these events. I have 2 functions that access a shared queue from separate threads. I'd use a lock, but since one of the threads needs to sleep-wait, I wasn't sure how to release the lock.
class Scheduler
{
SortedDictionary <DateTime, Action> _queue;
EventWaitHandle _sync;
// Runs on its own thread
void Run ()
{
while (true)
{
// Calculate time till first event
// If queue empty, use pre-defined value
TimeSpan timeDiff = _queue.First().Key - DateTime.Now;
// Execute action if in the next 100ms
if (timeDiff < 100ms)
...
// Wait on event handle for time
else
_sync.WaitOne (timeDiff);
}
}
// Can be called by any thread
void ScheduleEvent (Action action, DataTime time)
{
_queue.Add (time, action);
// Signal thread to wake up and check again
_sync.Set ();
}
}
While this is somewhat geared towards C#, I'd be happy to hear a general solution to this. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好的,用监视器/脉冲取 2。
OK, take 2 with Monitor/Pulse.
问题很容易解决,确保WaitOne在锁外。
_queueLock 是一个私有辅助对象。
The problem is easily solved, make sure the WaitOne is outside the lock.
_queueLock is a private helper object.
既然您的目标是在特定时间段后安排任务,为什么不直接使用 System.Threading.Timer 呢?它不需要专用线程进行调度,并利用操作系统来唤醒工作线程。我已经使用过这个(删除了一些注释和其他计时器服务功能):
Since your goal is to schedule a task after a particular period of time, why not just use the System.Threading.Timer? It doesn't require dedicating a thread for the scheduling and takes advantage of the OS to wake up a worker thread. I've used this (removed some comments and other timer service functionality):
监视器是为这种情况创建的,简单的问题可能会给应用程序带来很大的成本,我对此的解决方案非常简单,如果您想让关闭变得容易实现:
}
}
The monitores were created for this kind of situation, simple problems that can cost mutch for the application, i present my solution to this very simple and if u want to make a shutdown easy to implement:
}
}