21xrx.com
2024-09-19 10:01:50 Thursday
登录
文章检索 我的文章 写文章
C++类中创建线程
2023-07-08 09:19:58 深夜i     --     --
C++ 线程 创建

在C++中,可以通过多线程来实现异步处理、提高程序的并发度,甚至进行分布式计算。而在类中创建线程则可以更好地体现面向对象的思想。

为了在类中创建线程,需要使用C++11中新引入的std::thread类。下面是一个示例:


class MyClass {

public:

  void start() {

    thread_ = std::thread(&MyClass::doSomething, this);

  }

  void join() {

    thread_.join();

  }

private:

  std::thread thread_;

  

  void doSomething()

    // ...

  

};

在这个例子中,我们定义了一个MyClass类,并为其创建了一个std::thread对象thread_。函数start()用于启动该线程,传入的函数指针为doSomething(),而this则表示该函数是MyClass的成员函数。join()函数则用于等待线程执行完毕。

注意,我们必须使用std::thread对象来管理线程,而不能直接创建线程对象。同时,我们也需要确保线程函数doSomething()不会访问MyClass对象的非静态成员,否则可能会出现竞态条件。

除此之外,我们还可以使用lambda表达式来传递参数以及启动线程,例如:


class MyClass {

public:

  void start(int arg) {

    thread_ = std::thread([this, arg] { doSomething(arg); });

  }

  void join() {

    thread_.join();

  }

private:

  std::thread thread_;

  void doSomething(int arg)

    // ...

  

};

这段代码中,我们使用lambda表达式替代了函数指针的形式,并用[arg]来捕获arg参数。在本例中,arg为整型变量,但我们也可以传递其他类型的参数。

在使用类创建线程时,我们需要注意以下几点:

1. 构造函数中不要启动线程。类似以下代码是不正确的:


class MyClass {

public:

  MyClass() {

    thread_ = std::thread(&MyClass::doSomething, this);

  }

private:

  std::thread thread_;

  

  void doSomething()

    // ...

  

};

因为此时类对象可能还未完成构造,如果线程启动的太早,可能导致访问未初始化的变量,造成程序崩溃。

2. 析构函数中要等待线程结束。如果类对象被销毁时线程仍未结束,可能会导致程序异常。因此,需要在析构函数中调用join()函数等待线程结束。


class MyClass {

public:

  ~MyClass() {

    join();

  }

private:

  std::thread thread_;

  void join() {

    if(thread_.joinable()) {

      thread_.join();

    }

  }

};

3. 考虑竞态条件。在线程函数中要尽量避免访问类的非静态成员,否则可能会出现竞态条件。如果必须要访问,则需要使用互斥锁等同步机制来保护共享资源。

在C++类中创建线程可以更好地体现面向对象的设计思想,并确保程序的正确性和可靠性。尽管可能会增加一些复杂性,但好处也是显而易见的。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复