簡體   English   中英

在向量中插入元素時應該使用互斥量嗎?

[英]Should mutex be used when inserting element in vectors?

我知道在嘗試從向量中刪除元素時需要互斥量。

所以,我寫了一個示例代碼來檢查這個。

class Test
{
public:
    Test(int idx) : m_index(idx) {}
    int     m_index = { -1 };
    int     m_count = { 0 };
};
std::vector<std::unique_ptr<Test>>  m_vec;
std::mutex                          m_mutex;


void foo1() // print element data
{
    while (true)
    {
        std::unique_lock ulock(m_mutex);
        for (auto& e : m_vec)
        {
            e->m_count++;
            printf("%d : Count : %d\n", e->m_index, e->m_count);
        }
        ulock.unlock();
        std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }
}

void foo2() // Only insert element
{ 
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> dis(0, 99);

    while (true)
    {
        int t = dis(gen);
        if (t >= 0 && t < 10)
        {
            //std::unique_lock ulock(m_mutex);
            m_vec.push_back(std::make_unique<Test>(m_vec.size()));
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(t));
    }
}

void foo3() // Only remove element
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> dis(0, 99);

    while (true)
    {
        int t = dis(gen);
        if (t >= 0 && t < 10)
        {
            std::unique_lock ulock(m_mutex);
            if (m_vec.empty() == false)
                m_vec.erase(m_vec.begin());
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(t));
    }
}

int main()
{
    m_vec.push_back(std::make_unique<Test>(1));
    m_vec.push_back(std::make_unique<Test>(2));
    m_vec.push_back(std::make_unique<Test>(3));
    
    std::thread t1(foo1);
    std::thread t2(foo2);
    std::thread t3(foo3);

    t1.join();
    t2.join();
    t3.join();

    return 0;
}

如果我在不使用互斥量的情況下繼續使用 erase(),幾乎會立即發生段錯誤。

所以我對 erase() 例程使用了互斥量,它似乎工作正常。

然而,大約 10 分鍾后,在 foo1() function 中引用 e 時發生 nullptr 異常。

Q1。 push_back在末尾插入數據。 但是為什么在中間點會出現NULL錯誤呢? 前任。 矢量大小:521,錯誤索引:129)

Q2。 使用 vector 和 deque 等有序容器時,插入函數中是否需要互斥量?

Q3。 無序容器呢? (比如,unorderd_map)(從 insert 中移除 mutex 並運行大約 20 分鍾沒有任何問題。)

foo2()正在訪問/修改mutex鎖之外的vector 因此, foo1()和/或foo3() (確實使用mutex )能夠與foo2()同時修改vector 那是未定義的行為

push_back最后插入數據時,為什么會出現中間點(ex. vector size: 521, error index: 129)Null點錯誤?

將新元素推入vector可能需要它重新分配其內部數組,從而將所有現有元素移動到新的 memory 塊。 您在沒有mutex鎖保護的情況下在foo2()中執行此操作,因此foo1()foo3()正在訪問的元素可能會意外消失。

vector中擦除元素不會重新分配內部數組,但它仍可能會在數組現有的 memory 內移動元素。

使用 vector 和 deque 等有序容器時,插入和刪除函數中是否需要互斥量?

是的。 所有標准容器都不是線程安全的,因此在跨線程邊界使用時必須對修改進行序列化。

無序容器呢? (比如,unorderd_map)(從 insert 中移除 mutex 並運行大約 20 分鍾沒有任何問題。)

一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM