|
我有兩個線程,
線程1接受網絡數據,存到隊列; 線程2取隊列,進行各種復雜的處理然后繪制到界面上; 想讓線程1有數據了通知線程2,線程2再取隊列,因為不通知的話,線程2一直在while循環檢索隊列時候有東西,很費cpu,怎么弄? 我現在用的是C#的ManualResetEvent,線程1給隊列中加數據時,置為有信號, 線程2中,隊列為空置為無信號,這樣問題是置了好多個有信號,好浪費 也想過有AutoResetEvent,就怕兩次set激活事件時間間隔太短會有問題........ 怎么辦啊????,不要循環檢查而是等到1的通知 |
|
#1 得分:20回復於: 2014-03-10 22:42:37
請百度 生產者與消費者。。。就會得到你想要的 |
|
|
#2 得分:0回復於: 2014-03-10 22:44:05
AutoResetEvent 用這個沒問題的,
就算你兩次Set 只要上次沒執行完,就是沒進入到WaitOne()阻塞,你執行多少次Set都沒用 |
|
|
#3 得分:0回復於: 2014-03-10 22:56:36
自動重置事件,兩次set時間間隔很小的話,另一個線程WaitOne繼續一次的,那就不對了, 線程1: 有數據1->加入隊列->AutoResetEvent.set() 有數據2->加入隊列->AutoResetEvent.set() 線程2: while(true) { AutoResetEvent.WaitOne(); 取隊列 ....進行其他較耗時操作 } 線程2只循環一次,取一次隊列啊,我要想取兩次值;或者用其他辦法,只要讓線程2別 這樣: whiile(true) { ---------------->這樣很消耗cpu,或者會搶占其他線程cpu的 object obj = queue.deueue();//取頭元素 if(null == obj) { ....進行其他較耗時操作 } } ? |
|
#4 得分:20回復於: 2014-03-10 23:05:21
你搞錯了吧 要這樣子 線程1 有數據調用XXXEnQueue private void XXXEnQueue(xxx) 進隊列 { lock(queue) { queue.Enqueue(xxx); } auto.Set(); } private xxx XXXDequeue() //取頭元素 { lock(queue) { return queue.Dequeue(); } } 線程2 whiile(auto.WaitOne()) 這樣就成了 { while(queue.Count>0) { object obj = XXXDequeue(); if(null == obj) { ....進行其他較耗時操作 } } } |
|
|
#5 得分:0回復於: 2014-03-10 23:29:17
那什么時候reset()?還有多個線程之間都可以auto.Set()嗎?沒加鎖啊
|
|
#6 得分:0回復於: 2014-03-10 23:30:05
那什么時候reset()?還有多個線程之間都可以auto.Set()嗎?沒加鎖啊 |
|
#7 得分:0回復於: 2014-03-10 23:46:34
你去reset()他做啥,根本不用reset();
多個線程之間當然可以auto.Set(),你要了解生產者與消費者。關系。而不是一腦子在set reset上 |
|
|
#8 得分:0回復於: 2014-03-11 13:19:19
我說的是手動事件reset;
您沒聽懂我的原問題........ 如果用自動事件會是這樣(有問題的): thread1 接data1時加入隊列,set觸發事件后thread2會把waitone走過后立馬變為無信號, 接data2后加入隊列,set觸發事件后thread2會把waitone走過后立馬變為無信號, 如果thread1中兩次set時間間隔很小,thread2只會把waitone走過一次,就不再讀數據了........... |
|
#9 得分:0回復於: 2014-03-11 22:00:07
用Monitor.Pulse解決!
|


