【问题标题】:Function Objects & multithreading Pool giving same thread ID函数对象和多线程池提供相同的线程 ID
【发布时间】:2021-05-04 08:49:40
【问题描述】:

对于下面的程序,线程池总是选择相同的线程 ID 0x7000095f9000!为什么这样? 每次推送 condi.notify_one() 是否应该同时唤醒所有线程?选择相同线程 ID 的原因可能是什么?

计算机支持 3 个线程。 有关使用函数对象的任何其他信息都会有所帮助!

O/P

Checking if not empty
Not Empty
0x700009576000 0
Checking if not empty
Checking if not empty
Checking if not empty
Not Empty
0x7000095f9000 1
Checking if not empty
Not Empty
0x7000095f9000 2
Checking if not empty
Not Empty
0x7000095f9000 3
Checking if not empty
Not Empty
0x7000095f9000 4
Checking if not empty
Not Empty
0x7000095f9000 5
Checking if not empty

代码

#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <condition_variable>
#include <chrono>

using namespace std;

class TestClass{

public:
    void producer(int i) {
        unique_lock<mutex> lockGuard(mtx);
        Q.push(i);
        cond.notify_all();
    }


    void consumer() {
            {
                unique_lock<mutex> lockGuard(mtx);
                cout << "Checking if not empty" << endl;
                cond.wait(lockGuard, [this]() {
                    return !Q.empty();
                });
                cout << "Not Empty" << endl;
                cout << this_thread::get_id()<<" "<<Q.front()<<endl;
                Q.pop();
            }
    };

    void consumerMain() {
        while(1) {
            consumer();
            std::this_thread::sleep_for(chrono::seconds(1));
        }
    }

private:
    mutex mtx;
    condition_variable cond;
    queue<int> Q;

};


int main()
{
    std::vector<std::thread> vecOfThreads;
    std::function<void(TestClass&)> func = [&](TestClass &obj) {
        while(1) {
            obj.consumer();
        }
    };

    unsigned MAX_THREADS = std::thread::hardware_concurrency()-1;
    TestClass obj;
    for(int i=0; i<MAX_THREADS; i++) {
        std::thread th1(func, std::ref(obj));
        vecOfThreads.emplace_back(std::move(th1));
    }

   for(int i=0; i<4*MAX_THREADS/2; i++) {
       obj.producer(i);
   }
    for (std::thread & th : vecOfThreads)
    {
        if (th.joinable())
            th.join();
    }
    return 0;
}

有关使用函数对象的任何其他信息都会有所帮助!提前致谢!! 有其他指针吗?

【问题讨论】:

  • 也许让线程做“更多”或“真正”的工作。您无法控制操作系统如何调度您的线程,因此一个线程可能会消耗所有工作

标签: c++ multithreading


【解决方案1】:

在您的情况下,消费者线程中发生的 mutex 的非常短的解锁很可能会让正在运行的线程一次又一次地获取锁。

如果您改为通过调用 consumerMain(它会休眠一点)而不是 consumer 来模拟从队列中挑选工作负载后正在完成的一些工作,您可能会看到不同的线程在处理工作负载。

    while(1) {
        obj.consumerMain();
    }

【讨论】:

  • 在单生产者多消费者问题中,生产者和消费者是否应该持有相同的互斥锁?为生产者 (mtx_producer) 设置单独的互斥锁并为消费者线程设置单独的通用互斥锁是否更有意义? (mtx_common_consumer) 以获得高性能。
  • @user8707488 重要的是,对线程间共享资源的所有访问都受到保护,不会同时进行读/写操作。如果生产者想要对资源进行更改(如队列)并且消费者也想要访问资源,那么他们都应该使用相同的互斥体。
  • 您能否也对 Ted 的这个问题有所了解? stackoverflow.com/questions/67407668/…
猜你喜欢
  • 2016-04-18
  • 1970-01-01
  • 1970-01-01
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多