Mutex混淆的混乱

问题描述 投票:0回答:3

你好,我是多线程领域的新手,我对互斥锁感到困惑。我对有经验的人有关于多线程的问题。例如,在我的代码中,我有一个持有互斥量和条件变量的类,我将它们用于套接字通信。我将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()是什么锁。我只看到一个解释,即“如果两个线程想使用相同的源mutex.lock,例如stdinstdout,则被阻止”。

c++ multithreading locking std mutex
3个回答
0
投票

互斥锁是一次只能有一个线程的事物。如果没有线程接触到特定变量,除非它具有特定的互斥锁,那么我们说互斥锁会锁定该对象。

Mutexes通常用于防止多个线程同时接触某物。程序员应通过确保不查看或触摸共享资源,除非持有适用互斥对象的线程可以将特定互斥对象与特定共享资源相关联。

通常来说,除非您别无选择,否则您不想在拿着互斥锁时做任何“繁重的事情”。特别地,调用sleep_for是特别愚蠢和糟糕的。 recv的同上。


0
投票

来自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等。

不同的是:您的代码有两个问题:

  1. Recv_data函数(分配)的前两行将在函数返回后泄漏。看看RAII如何在现代C ++中进行初始化和分配
  2. 由于您正在使用线程锁和互斥锁,因此不需要条件变量。互斥体将保证线程之间的互斥,并且无需通知。但是,这在很大程度上取决于生成线程的方式。
  3. 您正在混合两个概念,套接字通信和线程。这似乎有点可疑。也就是说,尚不清楚从哪个上下文调用您的函数(不同的进程?在这种情况下,谈论线程没有意义)。

我建议您简化发送和接收单个变量(而不是数组)的代码,以先了解基础知识,然后再介绍更复杂的用例。


0
投票

我是否锁定了函数的变量或其他东西。

仅需绝对清楚:如果线程A保持某些互斥锁处于锁定状态,除了同时锁定同一互斥锁外,这不会阻止其他线程执行anything

[如果有人说“ Mutex M保护变量x,y和z,”这只是表达该程序已经过精心编写的简写方式,以便每个线程在访问任何这些变量之前始终锁定互斥量M。] >

这里的其他答案将对此进行更详细的介绍...

© www.soinside.com 2019 - 2024. All rights reserved.