21xrx.com
2024-12-22 15:20:31 Sunday
登录
文章检索 我的文章 写文章
C++多线程编程入门指南
2023-07-13 11:29:18 深夜i     --     --
C++ 多线程 编程 入门指南

C++是一种流行的编程语言,它被广泛地应用于各个领域,包括互联网、游戏、金融和科学计算等等。随着计算机硬件的发展,多核CPU已成为常态,因此,C++多线程编程已经成为了一个必备技能。本篇文章将提供一份C++多线程编程入门指南,帮助你掌握多线程编程的基本原理和方法。

1. 线程是什么?

线程是操作系统中最基本的执行单位,它类似于进程,但线程之间共享同一个地址空间。建立多个线程可以实现并发执行,提高程序的效率。C++标准库提供了std::thread类来支持多线程编程。

2. 线程的创建

创建线程需要使用std::thread类的构造函数。下面是一个例子:


#include <iostream>

#include <thread>

void threadFunc()

{

  std::cout << "Hello from thread!\n";

}

int main()

{

  std::thread t(threadFunc);

  t.join();

  return 0;

}

在上面的例子中,我们定义了一个简单的线程函数threadFunc,并在main函数中创建了一个std::thread对象t。std::thread的构造函数需要一个函数指针作为参数,表示要在新线程中执行的函数。我们把threadFunc作为参数传递给std::thread的构造函数。最后,通过调用t.join(),我们等待线程执行完毕再继续执行主线程。

3. 线程的传参和返回值

线程执行的函数可以有多个参数,我们可以通过构造函数的参数列表进行传递。下面是一个例子:


#include <iostream>

#include <thread>

void threadFunc(int x, int y)

{

  std::cout << "x + y = " << x + y << '\n';

}

int main()

{

  std::thread t(threadFunc, 2, 3);

  t.join();

  return 0;

}

在上面的例子中,我们修改了threadFunc函数,增加了两个参数x和y。在创建std::thread对象t时,我们通过构造函数的参数列表传递了这两个参数。

线程函数也可以返回一个值,可以使用std::promise和std::future来实现。下面是一个例子:


#include <iostream>

#include <thread>

#include <future>

void threadFunc(std::promise<int>& p)

{

  p.set_value(42);

}

int main()

{

  std::promise<int> p;

  std::future<int> f = p.get_future();

  std::thread t(threadFunc, std::ref(p));

  std::cout << "Answer: " << f.get() << '\n';

  t.join();

  return 0;

}

在上面的例子中,我们创建了一个std::promise对象p,并通过p.get_future()获取一个std::future对象f。std::promise对象p中的数据可以通过调用p.set_value()传递给std::future对象f。在调用f.get()时,如果线程还没有完成,就会阻塞等待。当线程完成之后,std::promise对象p就会将数据传递给std::future对象f,此时f.get()会返回42。

4. 线程的同步和互斥

在多线程编程中,不同线程之间共享同一块内存空间,因此可能会出现多个线程同时对同一变量进行读写操作的情况。这时就需要使用互斥量来保护共享数据,避免发生竞争条件。

C++标准库提供了std::mutex类来支持互斥量操作。通过调用std::mutex的lock()和unlock()方法,我们可以将需要保护的代码放在lock()和unlock()之间,实现互斥访问。下面是一个例子:


#include <iostream>

#include <thread>

#include <mutex>

std::mutex mtx;

void threadFunc(int& x)

{

  mtx.lock();

  ++x;

  std::cout << "x = " << x << '\n';

  mtx.unlock();

}

int main()

{

  int x = 0;

  std::thread t1(threadFunc, std::ref(x));

  std::thread t2(threadFunc, std::ref(x));

  t1.join();

  t2.join();

  return 0;

}

在上面的例子中,我们定义了一个共享的变量x,并在两个线程中对其进行读写操作。由于两个线程可能同时访问x,因此需要使用互斥量进行保护。

5. 线程的条件变量

线程的条件变量可以用来实现线程的通信和同步。C++标准库提供了std::condition_variable类来支持条件变量操作。下面是一个例子:


#include <iostream>

#include <thread>

#include <mutex>

#include <condition_variable>

std::mutex mtx;

std::condition_variable cv;

bool done = false;

void workerThread()

{

  std::unique_lock<std::mutex> lock(mtx);

  while(!done)

  {

    cv.wait(lock);

  }

  std::cout << "Worker thread done!\n";

}

int main()

{

  std::thread t(workerThread);

  std::this_thread::sleep_for(std::chrono::seconds(5));

  done = true;

  cv.notify_one();

  t.join();

  return 0;

}

在上面的例子中,我们定义了一个bool变量done,并在workerThread函数中使用while循环和std::condition_variable的wait方法进行等待,直到done变量变为true。在main函数中,我们通过调用std::this_thread::sleep_for方法让主线程等待5秒钟,然后将done变量设为true,并通过调用std::condition_variable的notify_one方法通知workerThread线程,使其从wait方法中返回并继续执行。最后,我们调用std::thread的join方法等待workerThread线程结束。

总结

以上介绍了C++多线程编程的基本知识点,包括线程的创建、传参和返回值、同步和互斥、以及条件变量的使用。多线程编程是一种非常重要的技能,它可以提高程序的效率和响应速度。在进行多线程编程时,必须注意线程安全和竞争条件等问题。希望本篇文章能够帮助你入门C++多线程编程。

  
  

评论区

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