std::mutex
mutex
是一种多线程变成中的同步原语,它能够让共享数据不被多个线程同时访问,它不支持递归得对互斥对象上锁构造函数
std::mutex::mutex
constexpr mutex() noexcept;(1)
mutex( const mutex& ) = delete;(2)
(1)构造mutex实例,mutex
实例构造完成之后是处于unlocked
状态
(2)mutex的拷贝构造函数是不存在的
std::mutex::~mutex
析构函数
销毁互斥变量
若互斥为任何线程占有,或若任何线程在保有任何互斥的所有权时终止,则行为未定义
赋值运算符,不存在
std::mutex::lock
锁定互斥。若另一线程已锁定互斥,则到 lock 的调用将阻塞执行,直至获得锁
错误发生时抛出 std::system_error ,包括底层操作系统阻止 lock 满足其规定的错误。在抛出任何异常的情况下,不锁定互斥。所以,直接使用mutex的lock成员是无处法处理异常的情况。
#include
#include
#include
#include int g_num = 0; // protected by g_num_mutex 共享数据
std::mutex g_num_mutex;void slow_increment(int id)
{ for (int i = 0; i < 3; ++i) { g_num_mutex.lock();++g_num;std::cout << id << " => " << g_num << '
';g_num_mutex.unlock();//chrono是C++的时间库,提供1s线程的休眠std::this_thread::sleep_for(std::chrono::seconds(1));}
}int main()
{ //0号线程和1号线程交叉执行对全局变量g_num对累加操作,执行完成之后sleep 1秒std::thread t1(slow_increment, 0);std::thread t2(slow_increment, 1);t1.join();t2.join();
}
输出如下
0 => 1
1 => 2
0 => 3
1 => 4
0 => 5
1 => 6
std::mutex::try_lock
尝试锁定互斥。立即返回。成功获得锁时返回 true ,否则返回 false。
若此操作返回 true ,则同一互斥上的先前 unlock() 操作同步于(定义于 std::memory_order )它。注意若此操作返回 false ,则先前的 lock() 不与之同步
#include
#include
#include
#include // std::coutstd::chrono::milliseconds interval(100);std::mutex mutex;
int job_shared = 0; // 两个线程都能修改 'job_shared',// mutex 将保护此变量int job_exclusive = 0; // 只有一个线程能修改 'job_exclusive'// 不需要保护// 此线程能修改 'job_shared' 和 'job_exclusive'
void job_1()
{ std::this_thread::sleep_for(interval); // 令 'job_2' 持锁while (true) { // 尝试锁定 mutex 以修改 'job_shared'if (mutex.try_lock()) { std::cout << "job shared (" << job_shared << ")
";mutex.unlock();return;} else { // 不能获取锁以修改 'job_shared'// 但有其他工作可做++job_exclusive;std::cout << "job exclusive (" << job_exclusive << ")
";std::this_thread::sleep_for(interval);}}
}// 此线程只能修改 'job_shared'
void job_2()
{ mutex.lock();std::this_thread::sleep_for(5 * interval);++job_shared;mutex.unlock();
}int main()
{ /*可以看到job1中的实现,使用的是try_lock获取锁,因为刚开始job1线程会进行100毫秒的休眠,所以cpu会先去执行job2,但是job2使用的是lock成员所以在job2中sleep 500毫秒的过程中执行job1时try_lock返回false,则执行exclusive输出.当job2获取不到锁,job1休眠结束之后释放锁,则job1重新获取锁成功*/std::thread thread_1(job_1);std::thread thread_2(job_2);thread_1.join();thread_2.join();
}
输出如下
job exclusive (1)
job exclusive (2)
job exclusive (3)
job exclusive (4)
job shared (1)
std::mutex::unlock
解锁mutex实例
使用前提是当前线程必须被mutex的实例锁定,否则改函数的调用是未定义的
注意,当前成员与lock()
成员,一般不直接调用,因为对异常情况的处理并不友好(程序锁定期间发生异常,进程就直接退出),所以一般与std::unique_lock 与 std::lock_guard 管理排他性锁 一起使用
具体使用实例可以参考如上两个代码。
mutex互斥变量,并提供来了独占锁特性。为C++提供了多线程访问共享数据的保护措施,同时引入了像unique_lock
和lock_gurad
异常处理锁机制来规避mutex
的成员处理异常情况的不足。
有时候因为业务需要,对某些非线程函数,比如mktime,需要使用互斥锁,可以参照example/blacklist-1或者channel_stats里面的用法 首先插件顶部声明 static TSMutex sites_mutex; 在TSPluginInit()中初始化 sites_mutex = TSMutexCreate...
在编写ATS插件的过程中,发现使用mktime会偶尔出现段错误, 经过网上调研,发现mktime等函数不是线程安全的, 于是编写下面的代码进行测试. 注意加锁和不加锁区别很大, 在mktime中使用多线程, 加上互斥锁就没有问题. //gcc -g mktime_multithread.c -o mktime_multithr...
经过长期探索,发现一个不需要手动设置线程休眠时间(e.g. std::this_thread::sleep_for(std::chrono::microseconds(1)))的代码: Github: https://github.com/log4cplus/ThreadPool #ifndef THREAD_POOL_H_7e...
nth_element(first,nth,last) first,last 第一个和最后一个迭代器,也可以直接用数组的位置。 nth,要定位的第nn 个元素,能对它进行随机访问. 将第n_thn_th 元素放到它该放的位置上,左边元素都小于它,右边元素都大于它. 测试代码: http://www.cplusplus.com...
c/c++老版本的rand()存在一定的问题,在转换rand随机数的范围,类型或者分布时,常常会引入非随机性。
定义在
jsoncpp 是一个C++ 语言实现的json库,非常方便得支持C++得各种数据类型到json 以及 json到各种数据类型的转化。 一个json 类型的数据如下: {"code" : 10.01,"files" : "","msg" : "","uploadid" : "UP000000" } 这种数据类型方便我们人阅读以...
问题如下: 已知一组数(其中有重复元素),求这组数可以组成的所有子集中,子 集中的各个元素和为整数target的子集,结果中无重复的子集。 例如: nums[] = [10, 1, 2, 7, 6, 1, 5], target = 8 结果为: [[1, 7], [1, 2, 5], [2, 6], [1, 1, 6]] 同样之前有...
通过multibranch类型的pipeline job使得对于多个branch的支持更加简单。只需要创建一个multibranch job,jenkins将自动地为所有的branch创建job。 文章来自:http://www.ciandcd.com文中的代码来自可以从github下载: https://github.com/c...
Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,MapReduce则为海量的数据提供了计算。 HDFS是Google File System(GFS)的开源实现,MapReduce是Google MapReduce的开源实现。 HDFS和MapReduce实现是完全分离的,并不是没有H...