互斥锁住困惑
Mutex locked confusion
你好,我对互斥锁感到困惑。我有一个关于多线程的问题要问有经验的人。例如,在我的代码中,我有保存互斥锁和条件变量的类,我将它们用于套接字通信。我使用mutex.lock()
锁定函数的变量,但我无法理解我锁定的内容。我是否锁定了函数的变量或其他东西。 我使用了unique_lock
,因为我想使用condition_variable
并锁定函数的变量,但我不知道它是否有效。我想创建相互等待的发送方和接收方。
我的接收数据功能
void connect_tcp::Recv_data(SOCKET s,mms_response &response,Signals *signals,bool &ok,ıvır_zıvır &ıvır) {
LinkedList** list = new LinkedList * [1000];
uint8_t* buffer = new uint8_t [10000];
//ok = false;
unique_lock <mutex> lck(ıvır.mutex);
if (ıvır.for_data == true) {
dataready = true;
}
ıvır.cv.wait(lck, [] {return dataready; });
this_thread::sleep_for(1s);
recv(s, (char*)buffer, 10000, 0);
dataready = false;
decode_bytes(response,buffer, list,signals);
ok = true;
ıvır.ıvır_control--;
}
我的发送数据功能
int connect_tcp::send_data(SOCKET s, mms_response &response,LinkedList** list,int &j,bool &ok, ıvır_zıvır& ıvır) {
/*this_thread::sleep_for(0.3s);*/
int i = 0;
int k = 0;
ıvır.mutex.lock();
uint8_t* buffer = new uint8_t[10000];
while (i<j)
{
for (auto it = list[i]->data.begin(); it != list[i]->data.end(); it++)
{
buffer[k]=*it;
k++;
}
i++;
}
int jk = 0;
jk= send(s, (const char*)buffer, list[0]->size, 0);
cout << jk << " Bytes sent" << endl;
dataready = true;
this_thread::sleep_for(1s);
ıvır.mutex.unlock();
ıvır.cv.notify_one();
if (jk == -1) {
exit(-1);
}
i = 0;
while (i<j) {
delete list[i];
i++;
}
j = 1;
return jk;
}
我读了很多书和条目,但没有人解释mutex.lock()
什么是锁定。我只看到一个解释是"如果 2 个线程想要使用相同的源mutex.lock
则被阻止,例如stdin
和stdout
"。
互斥锁是一次只能有一个线程的东西。如果没有线程接触特定变量,除非它具有特定的互斥锁,那么我们说互斥锁锁定了该变量。
互斥体通常用于防止多个线程同时接触某些内容。程序员可以通过确保共享资源不会被查看或触及,而不是由持有适用互斥锁的线程查看或触摸,从而将特定的互斥体与特定的共享资源相关联。
一般来说,除非你别无选择,否则你不想在持有互斥锁时做任何"重"的事情。特别是,称呼sleep_for
特别愚蠢和糟糕。同上recv
.
我是否锁定了函数的变量或其他东西。
只是要绝对清楚:如果线程 A 保持锁定某个互斥锁 M,则除了同时锁定相同的互斥锁 M 之外,这不会阻止其他线程执行任何操作。
如果有人说"Mutex M 保护变量 x、y 和 z",这只是一种简写方式,即程序经过精心编写,因此每个线程在访问任何这些变量之前始终锁定互斥 M。
这里的其他答案对此进行了更详细的介绍......
来自 cpp首选项
The mutex class is a synchronization primitive that can be used to protect shared data from being simultaneously accessed by multiple threads.
顾名思义,互斥锁是一个互斥状态持有者,它可以以原子方式在线程之间公开单个状态(锁定状态(。锁定通过不同的机制实现,例如unique_lock、shared_lock等。
另一方面:您的代码有几个问题:
- 前两行 在函数返回后Recv_data函数(分配(将泄漏。 查看 RAII 了解如何在现代 C++ 中初始化和分配
- 由于您使用的是线程锁和互斥锁,因此不需要条件变量。 互斥锁将保证线程的互斥,无需通知。但是,这在很大程度上取决于您生成线程的方式。
- 您混合了两个概念,即套接字通信和线程。这似乎有点可疑。也就是说,不清楚你的函数是从哪个上下文中调用的(不同的进程?在这种情况下,谈论线程是没有意义的(。
我建议您简化发送和接收单个变量(而不是数组(的代码,以便首先了解基础知识,然后再转到更复杂的用例。
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 与互斥锁相比,旋转锁可以保证上下文切换
- 我应该在锁定TBitmap画布后解锁它吗
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 具有两个独占锁组的共享锁
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- condition_variable、引用和线程:谁拥有锁?
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- 使用 std::async 时死锁,将来作为成员
- 如何调试读写器锁的死锁?
- 为什么我的 HWID 锁接受任何acceptedSerial_2值
- 生产者使用者在 cpp 中使用互斥锁的问题
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- 在通知提升间处理条件变量时未按住锁会导致问题
- 每次使用带有LOCK_EX标志的LOCK_NB时,相同的程序/进程都会获取锁
- 如何降低生产者获得锁的可能性,而消费者在使用std::condition_variable时无法获得锁?
- 通知条件变量后使用互斥锁
- (共享)C++中的互斥锁
- 如果两个线程相互依赖,则 cpp 线程连接应使用连接导致死锁
- 互斥锁住困惑