当封装到类中时,Pthread只使用一个线程

Pthread using only one thread when encapsulated into a class

本文关键字:线程 一个 封装 Pthread      更新时间:2023-10-16

我不明白为什么当"&;在类中,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封装成类

女士t_thread = 4056.75只Pthread

女士t_thread = 2619.55

我的环境是Ubuntu 16.04,我使用System Monitor来检查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方法。你的析构函数已经做到了这一点,当线程向量是clear() -ed时,它将被触发。进一步。我们为线程保留空间,并在vector中就地构造它们。

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