Ứng dụng bàn điều khiển có 3 luồng: Main, T1, T2. Mục đích là để 'tín hiệu' cả T1, T2 (và để cho họ làm một số công việc) từ các chủ đề chính trong độ trễ thấp nhất càng tốt (ms)Độ trễ thấp giữa các luồng trong cùng một quá trình
LƯU Ý:
- xin vui lòng bỏ qua Jitter , GC vv (tôi có thể xử lý đó)
- chi phí cuộc gọi ElapsedLogger.WriteLine dưới 50ns (nano giây)
Hãy nhìn vào mã bên dưới:
012.mẫu 1
class Program
{
private static string msg = string.Empty;
private static readonly CountdownEvent Countdown = new CountdownEvent(1);
static void Main(string[] args)
{
while (true)
{
Countdown.Reset(1);
var t1 = new Thread(Dowork) { Priority = ThreadPriority.Highest };
var t2 = new Thread(Dowork) { Priority = ThreadPriority.Highest };
t1.Start();
t2.Start();
Console.WriteLine("Type message and press [enter] to start");
msg = Console.ReadLine();
ElapsedLogger.WriteLine("Kick off!");
Countdown.Signal();
Thread.Sleep(250);
ElapsedLogger.FlushToConsole();
}
}
private static void Dowork()
{
string t = Thread.CurrentThread.ManagedThreadId.ToString();
ElapsedLogger.WriteLine("{0} - Waiting...", t);
Countdown.Wait();
ElapsedLogger.WriteLine("{0} - Message received: {1}", t, msg);
}
}
Output:
Type message and press [enter] to start
test3
20141028 12:03:24.230647|5 - Waiting...
20141028 12:03:24.230851|6 - Waiting...
20141028 12:03:30.640351|Kick off!
20141028 12:03:30.640392|5 - Message received: test3
20141028 12:03:30.640394|6 - Message received: test3
Type message and press [enter] to start
test4
20141028 12:03:30.891853|7 - Waiting...
20141028 12:03:30.892072|8 - Waiting...
20141028 12:03:42.024499|Kick off!
20141028 12:03:42.024538|7 - Message received: test4
20141028 12:03:42.024551|8 - Message received: test4
Trong mã 'trễ' ở trên là khoảng 40-50μs. Cuộc gọi báo hiệu CountdownEvent rất rẻ (dưới 50ns) nhưng các luồng T1, T2 bị treo và phải mất thời gian để đánh thức chúng.
mẫu 2
class Program
{
private static string _msg = string.Empty;
private static bool _signal = false;
static void Main(string[] args)
{
while (true)
{
_signal = false;
var t1 = new Thread(Dowork) {Priority = ThreadPriority.Highest};
var t2 = new Thread(Dowork) {Priority = ThreadPriority.Highest};
t1.Start();
t2.Start();
Console.WriteLine("Type message and press [enter] to start");
_msg = Console.ReadLine();
ElapsedLogger.WriteLine("Kick off!");
_signal = true;
Thread.Sleep(250);
ElapsedLogger.FlushToConsole();
}
}
private static void Dowork()
{
string t = Thread.CurrentThread.ManagedThreadId.ToString();
ElapsedLogger.WriteLine("{0} - Waiting...", t);
while (!_signal) { Thread.SpinWait(10); }
ElapsedLogger.WriteLine("{0} - Message received: {1}", t, _msg);
}
}
Output:
Type message and press [enter] to start
testMsg
20141028 11:56:57.829870|5 - Waiting...
20141028 11:56:57.830121|6 - Waiting...
20141028 11:57:05.456075|Kick off!
20141028 11:57:05.456081|6 - Message received: testMsg
20141028 11:57:05.456081|5 - Message received: testMsg
Type message and press [enter] to start
testMsg2
20141028 11:57:05.707528|7 - Waiting...
20141028 11:57:05.707754|8 - Waiting...
20141028 11:57:57.535549|Kick off!
20141028 11:57:57.535576|7 - Message received: testMsg2
20141028 11:57:57.535576|8 - Message received: testMsg2
này thời gian 'trễ' là khoảng 6-7μs. (nhưng CPU cao) Điều này là do T1, T2 chủ đề được buộc phải hoạt động (họ không làm gì chỉ cần ghi thời gian CPU)
Trong ứng dụng 'thực' tôi không thể quay CPU như vậy (Tôi có nhiều chủ đề đang hoạt động và nó sẽ làm cho nó tồi tệ hơn/chậm hơn hoặc thậm chí giết chết máy chủ).
Có bất kỳ thứ gì tôi có thể sử dụng thay vào đó để giảm độ trễ xuống khoảng 10-15 μ? Tôi đoán với nhà sản xuất/mẫu người tiêu dùng nó sẽ không thực hiện nhanh hơn sử dụng CountdownEvent. Chờ/Pulse cũng đắt hơn CountdownEvent.
Tôi có thể đạt được điều gì trong mẫu 1 hay nhất?
Mọi đề xuất?
Tôi cũng sẽ thử các ổ cắm thô khi có thời gian.
Bạn đã điều tra 'ManualResetEventSlim' và' SemaphoreSlim' chưa? Điều gì về 'Monitor.Wait' và' Monitor.Pulse'? –
@JimMischel: Tôi đã thử tất cả chúng và kết quả là khá giống nhau. – Novitzky