c++多线程

多线程并发指的是在同一个进程中执行多个线程,线程是轻量级的进程,同一进程中的多个线程共享相同的地址空间,可以访问进程中的大部分数据,指针和引用可以在线程间进行传递。

简单创建使用

头文件:

#include 

创建线程:

第一种
std::thread myThread (thread_fun);  //创建线程myThread,线程中传入函数thread_fun
myThread.join();
---------------------------
第二种
std::thread myThread (thread_fun(100));
myThread.join();
---------------------------
第三种
std::thread (thread_fun,1).join();
  • detach方式,启动的线程自主在后台运行,当前的代码继续往下执行,不等待新线程结束。
  • join方式,等待启动的线程完成,才会继续执 执行下面的代码。

代码例:

#include 
#include 

using namespace std;

void thread_1()
{

  cout << "子线程1" << endl<

编译:g++ test.cc -o test -l pthread

运行:./test

结果:

可以发现执行多次,每次执行可能不相同,因为线程是并发进行的。

c++多线程_第1张图片c++多线程_第2张图片

同时可以发现“这是主线程”永远在三个线程执行结果后面,因为线程的执行方式是join,必须要等线程执行完了之后才可以执行接下来的代码(非声明join或detach的代码)。

 注:

可以使用joinable判断是join模式还是detach模式。

if (myThread.joinable()) foo.join()

 this_thread

std::this_thread::get_id()    获取线程id
std::this_thread::yield()    放弃线程执行,回到就绪状态
std::this_thread::sleep_for(std::chrono::seconds(1));    暂停1秒(sleep_until也可以达到类似的效果)

死锁

mutex

#include        // std::cout
#include          // std::thread
#include           // std::mutex

using namespace std;
mutex mtx1;          
mutex mtx2;
void print_block1 (int n, char c) {

  mtx1.lock();
  for (int i=0; i

c++多线程_第3张图片

 因为两个打印程序使用的是同一个mutex,所以互斥,不会同时执行。如果把第二个函数的mutex变量换成mtx2就会出现下面交替打印的情况:

c++多线程_第4张图片

lock_gaurd

作用:为了防止在线程使用mutex加锁后异常退出导致死锁的问题,建议使用lock_guard代替mutex。

(1) 创建即加锁,作用域结束自动析构并解锁,无需手工解锁
(2) 不能中途解锁,必须等作用域结束才解锁
(3) 不能复制

格式:template class lock_guard;

eg:lock_gurad lock(mtx)

unique_lock

unique_lock不仅可以使用在简单的临界代码段的互斥操作中,还可以使用在函数调用过程中

std::unique_lock  munique(mlock,参数);

参数可以是:

std::try_to_lock:会判断当前mutex能否被lock,如果不能被lock,可以先去执行其他代码

std::unique_lock munique(mlock, std::try_to_lock);
		if (munique.owns_lock() == true) {
			s += i;
		}
		else {
			// 执行一些没有共享内存的代码
		}
	}

std::defer_lock: 这个参数表示暂时先不lock,之后手动去lock,但是使用之前也是不允许去lock。一般用来搭配unique_lock的成员函数去使用。

std::unique_lock munique(mlock, std::defer_lock);
munique.lock();
s += i;
munique.unlock();       

还有一个成员函数是try_lock,和上面的try_to_lock参数的作用差不多,判断当前是否能lock,如果不能,先去执行其他的代码并返回false,如果可以,进行加锁并返回true

release函数,解除unique_lock和mutex对象的联系,并将原mutex对象的指针返回出来。

std::unique_lock munique(mlock);   // 这里是自动lock
std::mutex *m = munique.release();
s += i;
m->unlock();

参考:C++多线程unique_lock详解 - 腾讯云开发者社区-腾讯云

简单的场景,不涉及线程通信时,可以使用 lock_guard, 但是涉及函数调用或线程通信时 使用 unique_lock

参考:

一文详解C++多线程_非晚非晚的博客-CSDN博客

你可能感兴趣的:(c++)