C++并发编程(CH02)[ 转移thread所有权-03]

move 示例

std::ifstream是movable but not copyable,同理thread也是这样的对象.

void some_function();
void some_other_function();
std::thread t1(some_function);
std::thread t2=std::move(t1);
t1=std::thread(some_other_function); // The left item is a temporary object, and moving from temporaries is automatic and implicit
std::thread t3;
t3=std::move(t2);
t1=std::move(t3);                    //<--6 This assignment will terminate program!

(一个线程对象必须在退出函数的时候显示的调用detach或者join。否则会诱发std:terminate调用)

函数返回值可以是thread

std::thread f()
{
  void some_function();
  return std::thread(some_function);
}
std::thread g()
{
  void some_other_function(int);
  std::thread t(some_other_function,42);
  return t;
}

函数参数可以是thread

void f(std::thread t);
void g()
{

  void some_function();
  f(std::thread(some_function));
  std::thread t(some_function);
  f(std::move(t)); // move 的使用案例
}

RAII example

class scoped_thread
{
  std::thread t;
public:
  explicit scoped_thread(std::thread t_): 
    t(std::move(t_))
  {
    if(!t.joinable())                     
      throw std::logic_error(“No thread”);
  }
  ~scoped_thread()
  {
    t.join();                             
    // 慎用,如果这样不小心这样写类。则可能造成进程同步,实际没有多线程的并发优势。
  }
  scoped_thread(scoped_thread const&)=delete;
  scoped_thread& operator=(scoped_thread const&)=delete;
};
struct func;                                            
void f()
{
  int some_local_state;
  scoped_thread t(std::thread(func(some_local_state))); 
  do_something_in_current_thread();
}                                                       

vector储存thread对象群.

vector可以传递thread对象。采用move的方式

void do_work(unsigned id);
void f()
{
  std::vector<std::thread> threads;
  for(unsigned i=0;i<20;++i)
    {
      threads.push_back(std::thread(do_work,i));  //<--Spawn threads
    }
  std::for_each(threads.begin(),threads.end(),
                std::mem_fn(&std::thread::join)); //<--Call join() on each thread in turn
                //(std:mem_fn可以生成一个函数对象.这个函数对象供for_each调用)
}

void do_work(unsigned id);
void f()
{
    std::vector<std::thread> threads;
    for(unsigned i=0;i<20;++i)
    {
        threads.emplace_back(do_work,i);
    }
    for(auto& entry: threads)
        entry.join();
}

a joining thread class

boost库中有一个类似于下面的class,用来自动join线程.

class joining_thread
{
    std::thread t;
public:
    joining_thread() noexcept=default;
    template<typename Callable,typename ... Args>
    explicit joining_thread(Callable&& func,Args&& ... args):
        t(std::forward<Callable>(func),std::forward<Args>(args)...)
    {}
    explicit joining_thread(std::thread t_) noexcept:
        t(std::move(t_))
    {}
    joining_thread(joining_thread&& other) noexcept:
        t(std::move(other.t))
    {}
    joining_thread& operator=(joining_thread&& other) noexcept
    {
        if(joinable())
            join();
        t=std::move(other.t);
        return *this;
    }
    joining_thread& operator=(std::thread other) noexcept
    {
        if(joinable())
            join();
        t=std::move(other);
        return *this;
    }
    ~joining_thread() noexcept
    {
        if(joinable())
            join();
    }

    void swap(joining_thread& other) noexcept
    {
        t.swap(other.t);
    }
    std::thread::id get_id() const noexcept{
        return t.get_id();
    }
    bool joinable() const noexcept
    {
        return t.joinable();
    }
    void join()
    {
        t.join();
    }
    void detach()
    {
        t.detach();
    }

    std::thread& as_thread() noexcept
    {
        return t;
    }
    const std::thread& as_thread() const noexcept
    {
        return t;
    }
};
发布了127 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/luixiao1220/article/details/104626799