Cpp标准库多线程编程

更多使用

参考:https://en.cppreference.com/w/

thread类

//一个常用的构造函数形式
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );//参数均为右值引用,其为临时对象不会影响原来的对象
//线程的函数参数必须是一个没有返回值的函数
简单使用
#include <thread>//包含线程头文件
#include <iostream>

thread_local int g_num = 1;//定义一个线程变量,对于线程变量,每个线程都会有该变量的一个拷贝,互不干扰。该局部变量一直都在,直到线程退出为止,线程变量在线程执行过程当中必须有效,如此处若在main函数中使用detach将线程置为分离态,main执行结束会销毁g_num变量

void thredfun1()
{
	g_num++;
	std::cout<<"thread1 no arg"<<std::endl;
	std::cout<<"thread1 g_num: "<<g_num<<std::endl;
}

void thredfun2(int x,int y)
{
	g_num++;
	std::cout<<"thread2 arg:"<<x<<" "<<y<<std::endl;
	std::cout<<"thread2 g_num: "<<g_num<<std::endl;
}

int main()
{
	std::thread f1(thredfun1); 
	std::thread f2(thredfun2,2,3);
	//f1.detach();
	//f2.detach();//调用其使线程置为分离态,不用等待其执行结束后返回,若main函数比线程函数先执行结束,则不能在main函数中执行线程分离函数
	f1.join();
	f2.join();//等待线程结束后返回
	std::cout<<"main end"<<std::endl;
	return 0;
}

线程资源同步对象

std::mutex

互斥量版本作用
mutexC++11最基本的互斥量
timed_mutexC++11有超时机制的互斥量
recursive_mutexC++11可重入的互斥量
recursive_timed_mutexC++11结合 timed_mutex 和 recursive_mutex 特点的互斥量
shared_timed_mutexC++14具有超时机制的可共享互斥量
shared_mutexC++17共享的互斥量
使用RAII技术对mutex的封装
互斥量管理版本作用
lock_guardC++11基于作用域的互斥量管理
unique_lockC++11更加灵活的互斥量管理
shared_lockC++14共享互斥量的管理
scope_lockC++17多互斥量避免死锁的管理

使用RAII技术在类构造时调用锁的加锁函数,析构时调用函数的解锁函数,成员变量是一个锁的引用,大概为以下意思:

class RAII{
    public :
    RAII(mutex& t):mutex_(t){
        mutex_.lock()
    }
    ~RAII(){
        mutex_.unlock();
    }
    private:
    mutex& mutex_;
};

lock_guard使用示例:

{
	std::lock_guard<std::mutex> guard(mutex_);//初始化并加锁,括号内为锁的作用范围
	//在这里放被保护的资源操作
}
//出括号guard析构解锁

std::condition_variable

条件变量
void fun1()
{
    std::unique_lock<std::mutex> guard(mymutex);
		while ([true]or[flase])//此处不能使用if
		{				
			//如果获得了互斥锁,但是条件不合适的话,pthread_cond_wait会释放锁,不往下执行。
			//当发生变化后,条件合适,pthread_cond_wait将直接获得锁。
			mycv.wait(guard);
		}
}

void fun2()
{
    //释放信号量,通知等待线程
		mycv.notify_one();
}
虚假唤醒

变量的线程也有可能会醒来。我们将条件变量的这种行为称之为 虚假唤醒。因此将条件放在一个 while 循环中意味着光唤醒条件变量不行,还必须条件满足程序才能继续执行正常的逻辑。

另外一种系统调用被中断:pthread_cond_wait 是 futex 系统调用,属于阻塞型的系统调用,当系统调用被信号中断的时候,会返回 -1,并且把 errno 错误码置为EINTR。很多这种系统调用为了防止被信号中断都会重启系统调用(即再次调用一次这个函数)。但有的系统调用被中断可以系统自己重试,有的不可以重试的,不可以重试的需要调用者自己手动重试。此处使用while循环则相当于调用者自己重试。若不判断条件向下执行,则不符合代码逻辑,即当前条件不满足无法执行后续操作。若使用if则不会重新判断会直接向下执行,若条件不满足则有可能会引起程序的崩溃。

std::atomic

原子操作类
#include <atomic>
#include <iostream>

int main()
{
    std::atomic<int> value;
    value = 99;//atomic默认禁用拷贝构造函数,所以不不能使用    std::atomic<int> value = 99;但支持赋值操作
    //atomic& operator=( const atomic& ) = delete;禁用拷贝构造函数
    //T operator=( T desired );合法赋值

    std::cout<<value<<std::endl;

    //自增1,原子操作
    value++;
    std::cout<<value<<std::endl;

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值