正如標題所說,我正在嘗試編寫一個隊列,可以由多個線程寫入並由單個線程讀取。作爲一個額外的困難,我需要隊列輸入保持有序(先進先出)。這是我迷失的地方。互斥鎖不一定會按照鎖定的順序被喚醒,所以我不知道我可以用什麼來實現我想要的功能?下面是一個簡單的程序說明我想要做的事:線程安全FIFO /隊列(多個生產者,一個消費者)
#include "Queue.h"
#include <Windows.h>
#include <fstream>
#include <mutex>
using std::ofstream;
ofstream myFile("result.txt");
Queue<int> myQueue;
DWORD WINAPI WritingThread(LPVOID lpParam);
DWORD WINAPI LockingThread(LPVOID lpParam);
int main()
{
// This thread will block myQueue for 3 seconds
CreateThread(NULL, 0, LockingThread, NULL, 0, NULL);
// During the locked period, I ask myQueue to push numbers from 0 to 49
for (int i = 0; i < 50; i++)
CreateThread(NULL, 0, WritingThread, (LPVOID)new int(i), 0, NULL);
// If the mutex could wake up in order, myQueue would pop up the numbers in order, but it doesn't.
for (int i = 0; i < 50; i++)
myFile << myQueue.pop() << ",";
return EXIT_SUCCESS;
}
DWORD WINAPI LockingThread(LPVOID lpParam)
{
myQueue.lockQueueFor3Seconds();
return 0;
}
DWORD WINAPI WritingThread(LPVOID lpParam)
{
myQueue.push(*(int*)lpParam);
return 0;
}
該類隊列中的代碼被送往there, see the bottom of the article for full code.我所做的只是將用於測試目的的方法「lockQueueFor3Seconds」。該方法的定義是這樣的:
void lockQueueFor3Seconds()
{
std::unique_lock<std::mutex> mlock(mutex_);
Sleep(3000);
}
該測試的輸出是這樣的:
1,43,39,46,36,44,49,40,35,42,32,31,28,41,27,38,24,23,20,34,19,16,15,12,37,11,7,8,3,33,30,0,45,4,26,18,48,21,47,22,25,17,14,10,6,29,9,2,13,5
正如你所看到的,顯然不是有序的。謝謝你的幫助!
編輯:我修改了隊列,以便它爲每個推送調用分配一個數字,以表示它們的順序,當互斥鎖被解鎖時,隊列檢查以確保在添加元素之前它是正確的方法,否則返回等待。不知道我是否正確實施了這個,但它似乎有效!完整的代碼可以在there找到。
它們按照您將它們放入隊列的順序進行排序。假設你開始的線程按照你創建的順序運行,你錯了。嘗試在每個線程之間創建一個睡眠。 – kfsone
附註:爲什麼不使用std :: thread?避免'new',你有內存泄漏。 –
將優先級作爲參數傳遞給線程,並在優先級隊列中使用該優先級 –