如何解决为什么互斥锁不适用于链表实现的线程安全队列类?
我用链表实现了一个队列,我希望多个线程以正确的顺序推送元素。我使用互斥锁来锁定我的成员函数,但是打印到终端的数字仍然没有正确的顺序,应该是 1,2,3,4,5,6。相反,它会打印错误的顺序,例如 3,1,6。这意味着互斥锁没有工作。有人可以告诉我为什么吗?以及如何解决这个问题?
// Implement a queue<int>,need functions: push_front,back,pop_back,and print
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
struct ListNode {
ListNode* next;
int val;
ListNode(int x) {
val = x;
this->next = nullptr;
}
};
class Queue {
public:
Queue() {
head = new ListNode(0); // dummy head
tail = head;
}
void push_front(int x) { // add node at then end of linked list
lock_guard<mutex> lock(m);
tail->next = new ListNode(x);
tail = tail->next;
}
int pop_back() { // remove the first node of the linked list
lock_guard<mutex> lock(m);
ListNode* back = head->next;
if (back == nullptr) {
throw invalid_argument("empty queue");
}
head->next = back->next;
back->next = nullptr;
return back->val;
}
void print() {
lock_guard<mutex> lock(m);
ListNode* p = head->next;
while (p != nullptr) {
cout << p->val << endl;
p = p->next;
}
}
private:
mutable mutex m;
// Implement with linked list
ListNode* head;
ListNode* tail;
};
int main() {
Queue* queue = new Queue();
// Multiple threads push at the same time --> order is wrong
thread t1 = thread(&Queue::push_front,queue,1);
thread t2 = thread(&Queue::push_front,2);
thread t3 = thread(&Queue::push_front,3);
thread t4 = thread(&Queue::push_front,4);
thread t5 = thread(&Queue::push_front,5);
thread t6 = thread(&Queue::push_front,6);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
queue->print();
}
解决方法
正如许多用户所提到的,您对互斥锁含义的假设至少在(线程)顺序方面是错误的。在多线程上下文中,顺序通常是一种品质,它几乎总是系统地产生于您的业务逻辑和拟合数据类型,而不仅仅是来自单个编译器/语言内在函数。
您可以使用简单的单线程连续方法解决您的问题,或者,根据您的进一步目的,您可以将基础数据类型更改为支持偏序的类型(例如在 std::set 的意义上) ) 与并行写入访问相结合(不单独提及单个容器互斥锁,从而将整个并行方法减少到荒谬程度)。有些事情在这里是可能的,但这实际上取决于您的实际具体要求。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。