gpt4 book ai didi

c++ - Pthread封装成类时只使用一个线程

转载 作者:行者123 更新时间:2023-11-30 05:20:22 29 4
gpt4 key购买 nike

我不明白为什么当“封装”到一个类中时,pthread 只使用一个线程,而在使用对 pthread 函数的普通调用时它使用所有线程。应该是执行有问题。

请看下面的代码:

#include <iostream>
#include <vector>
#include <pthread.h>
#include <sys/time.h>


namespace {
class Functor {
public:
Functor(const std::vector<int> &v) :
m_v(v), m_res() {
}

Functor() : m_v(), m_res() {
}

void operator()() {
computeImpl();
}

std::vector<int> getResult() const {
return m_res;
}

private:
std::vector<int> m_v;
std::vector<int> m_res;

void computeImpl() {
//Long computation (remove duplicates)
for (size_t i = 0; i < m_v.size(); i++) {
bool duplicate = false;

for (size_t j = 0; j < m_res.size() && !duplicate; j++) {
if (m_v[i] == m_res[j]) {
duplicate = true;
}
}

if (!duplicate) {
m_res.push_back(m_v[i]);
}
}
}
};

void * thread(void * args) {
Functor* f = reinterpret_cast<Functor*>(args);
(*f)();
return 0;
}

double measureTimeMs() {
struct timeval tp;
gettimeofday(&tp,0);
return(1000.0*tp.tv_sec + tp.tv_usec/1000.0);
}

class MyThread {
public:
MyThread(void * (*func)(void *), void *arg) : m_pid() {
pthread_create(&m_pid, NULL, func, arg);
}

MyThread() : m_pid() { }

virtual ~MyThread() {
join();
}

void join() {
pthread_join(m_pid, NULL);
}

private:
pthread_t m_pid;
};
}

int main() {
//Pthread encapsulated into a class
size_t nb_threads = 4;
std::vector<MyThread> threads(nb_threads);
std::vector<Functor> functors(nb_threads);

std::vector<int> v(100000);
srand(0);
for (size_t i = 0; i < v.size(); i++) {
v[i] = rand();
}

double t_thread = measureTimeMs();
for (size_t i = 0; i < nb_threads; i++) {
functors[i] = Functor(v);
threads[i] = MyThread(thread, &functors[i]);
}

for (size_t i = 0; i < nb_threads; i++) {
threads[i].join();
}
t_thread = measureTimeMs() - t_thread;
std::cout << "Pthread encapsulated into a classs" << std::endl;
std::cout << "t_thread=" << t_thread << " ms" << std::endl;


//Only Pthread
std::vector<pthread_t> pid(nb_threads);
t_thread = measureTimeMs();
for (size_t i = 0; i < nb_threads; i++) {
functors[i] = Functor(v);
pthread_create(&pid[i], NULL, thread, &functors[i]);
}

for (size_t i = 0; i < nb_threads; i++) {
pthread_join(pid[i], NULL);
}
t_thread = measureTimeMs() - t_thread;
std::cout << "Only Pthread" << std::endl;
std::cout << "t_thread=" << t_thread << " ms" << std::endl;

return EXIT_SUCCESS;
}

输出:

Pthread encapsulated into a classs

t_thread=4056.75 ms

Only Pthread

t_thread=2619.55 ms

我的环境:Ubuntu 16.04,我使用系统监视器来检查 CPU 事件。在第一种情况下(封装),只有一个线程达到 100%,而在第二种情况下它使用 4 个线程达到 100%。

此外,我的电脑有 2 个核心/4 个线程。

最佳答案

您的线程设置正在引入拷贝。此外,这些拷贝的源在创建线程时被同步销毁(因此在下一个线程启动之前启动、运行和连接等)。并在伤口中加入最后的盐,连接也进行了两次。

更改设置:

std::vector<MyThread> threads;
std::vector<Functor> functors;

threads.reserve(nb_threads);
functors.reserve(nb_threads);

for (int i = 0; i < nb_threads; i++)
{
functors.emplace_back(v);
threads.emplace_back(thread, &functors[(size_t) i]);
}

// will fire all destructors, and consequently join.
threads.clear();

请注意,我们不会在此处触发 join 方法。您的析构函数已经这样做了,并且会在线程 vector 为 clear() 时触发。更远。我们为线程保留空间,并在 vector 中就地构建它们。

运行上面的代码应该可以得到你想要的相似度数。

关于c++ - Pthread封装成类时只使用一个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40678000/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com