正如标题所说,我正在尝试编写一个队列,可以由多个线程写入并由单个线程读取。作为一个额外的困难,我需要队列输入保持有序(先进先出)。这是我迷失的地方。互斥锁不一定会按照锁定的顺序被唤醒,所以我不知道我可以用什么来实现我想要的功能?下面是一个简单的程序说明我想要做的事:线程安全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',你有内存泄漏。 –
将优先级作为参数传递给线程,并在优先级队列中使用该优先级 –