互斥锁混乱
Mutex locked confusion
你好,我对互斥锁定感到困惑。我对有经验的人有一个关于多线程的问题。例如,在我的代码中,我有 class 保存互斥量和条件变量,我将它们用于套接字通信。我使用 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
”。
互斥量是一种只能在一个线程中同时拥有的东西。如果没有线程接触特定变量,除非它有特定的互斥锁,那么我们说互斥锁锁定了那个东西。
互斥通常用于防止多个线程同时接触某物。由程序员将特定互斥锁与特定共享资源相关联,方法是确保除了持有适用互斥锁的线程外,共享资源不会被查看或触及。
一般来说,除非您别无选择,否则您不想在持有互斥体时做任何事情 "heavy"。特别是,调用 sleep_for
是特别愚蠢和糟糕的。 recv
.
同上
来自 cppreference
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 函数(分配)中的前两行将在函数 returns 之后泄漏。查看 RAII 了解如何在现代 C++ 中初始化和分配
- 由于您使用的是线程锁和互斥锁,因此不需要条件变量。 mutex会保证线程的互斥,不需要通知。但是,这在很大程度上取决于您生成线程的方式。
- 您正在混合两个概念,即套接字通信和线程。这似乎有点可疑。也就是说,不清楚你的函数是从哪个上下文调用的(不同的进程?在这种情况下讨论线程是没有意义的)。
我建议您简化用于发送和接收单个变量(而不是数组)的代码,以便先了解基础知识,然后再转向更复杂的用例。
did i lock function's variables or another things.
绝对清楚一点:如果线程 A 锁定某个互斥量 M,那 不会 阻止其他线程做 任何事情 除了同时锁定同一个互斥量 M。
如果有人说 "Mutex M protects variables x, y, and z," 那只是一种 shorthand 的说法,即程序经过精心编写,因此每个线程在访问任何这些变量之前总是锁定互斥体 M。
此处的其他答案对此进行了更详细的介绍...
你好,我对互斥锁定感到困惑。我对有经验的人有一个关于多线程的问题。例如,在我的代码中,我有 class 保存互斥量和条件变量,我将它们用于套接字通信。我使用 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
”。
互斥量是一种只能在一个线程中同时拥有的东西。如果没有线程接触特定变量,除非它有特定的互斥锁,那么我们说互斥锁锁定了那个东西。
互斥通常用于防止多个线程同时接触某物。由程序员将特定互斥锁与特定共享资源相关联,方法是确保除了持有适用互斥锁的线程外,共享资源不会被查看或触及。
一般来说,除非您别无选择,否则您不想在持有互斥体时做任何事情 "heavy"。特别是,调用 sleep_for
是特别愚蠢和糟糕的。 recv
.
来自 cppreference
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 函数(分配)中的前两行将在函数 returns 之后泄漏。查看 RAII 了解如何在现代 C++ 中初始化和分配
- 由于您使用的是线程锁和互斥锁,因此不需要条件变量。 mutex会保证线程的互斥,不需要通知。但是,这在很大程度上取决于您生成线程的方式。
- 您正在混合两个概念,即套接字通信和线程。这似乎有点可疑。也就是说,不清楚你的函数是从哪个上下文调用的(不同的进程?在这种情况下讨论线程是没有意义的)。
我建议您简化用于发送和接收单个变量(而不是数组)的代码,以便先了解基础知识,然后再转向更复杂的用例。
did i lock function's variables or another things.
绝对清楚一点:如果线程 A 锁定某个互斥量 M,那 不会 阻止其他线程做 任何事情 除了同时锁定同一个互斥量 M。
如果有人说 "Mutex M protects variables x, y, and z," 那只是一种 shorthand 的说法,即程序经过精心编写,因此每个线程在访问任何这些变量之前总是锁定互斥体 M。
此处的其他答案对此进行了更详细的介绍...