C++相关闲碎记录(18)

1、strftime()的转换指示器

#include <locale>
#include <chrono>
#include <ctime>
#include <iostream>
#include <exception>
#include <cstdlib>
using namespace std;int main ()
{try {// query local time:auto now = chrono::system_clock::now();std::time_t t = chrono::system_clock::to_time_t(now);tm* nowTM = std::localtime(&t);// print local time with the global classic locale:locale locC;const time_put<char>& tpC = use_facet<time_put<char>>(locC);// use single conversion specifiertpC.put (cout, cout, ' ', nowTM, 'x');cout << endl;// use format string:string format = "%A %x %I%p\n";  // format: weekday date hourtpC.put (cout, cout, ' ', nowTM,format.c_str(), format.c_str()+format.size() );// print local time with German locale:
#ifdef _MSC_VERlocale locG("deu_deu.1252");
#elselocale locG("de_DE");
#endifconst time_put<char>& tpG = use_facet<time_put<char>>(locG);tpG.put (cout, cout, ' ', nowTM, 'x');cout << endl;tpG.put (cout, cout, ' ', nowTM,format.c_str(), format.c_str()+format.size() );}catch (const std::exception& e) {cerr << "Exception: " << e.what() << endl;return EXIT_FAILURE;}
}
输出:
12/19/23
Tuesday 12/19/23 04PM
Exception: locale::facet::_S_create_c_locale name not valid

 2、用于字符分类的辅助函数

 3、随机数

#include <random>
#include <iostream>
#include <algorithm>
#include <vector>int main()
{// create default engine as source of randomnessstd::default_random_engine dre;// use engine to generate integral numbers between 10 and 20 (both included)std::uniform_int_distribution<int> di(10,20);for (int i=0; i<20; ++i) {std::cout << di(dre) << " ";}std::cout << std::endl;// use engine to generate floating-point numbers between 10.0 and 20.0// (10.0 included, 20.0 not included)std::uniform_real_distribution<double> dr(10,20);for (int i=0; i<8; ++i) {std::cout << dr(dre) << " ";}std::cout << std::endl;// use engine to shuffle elementsstd::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };//...std::shuffle (v.begin(), v.end(),  // rangedre);                // source of randomnessfor (int i=0; i<v.size(); ++i) {std::cout << v[i] << " ";}std::cout << std::endl;
}
输出:
10 11 18 15 15 12 10 17 17 20 14 15 19 10 10 15 17 10 14 10 
16.8677 19.3044 15.2693 16.5392 17.0119 17.622 10.4746 13.2823
5 2 8 4 3 6 7 1 9

4、分布

#include <random>
#include <map>
#include <string>
#include <iostream>
#include <iomanip>template <typename Distr, typename Eng>
void distr (Distr d, Eng e, const std::string& name)
{// print min, max and four example valuesstd::cout << name << ":" << std::endl;std::cout << "- min():  " << d.min() << std::endl; std::cout << "- max():  " << d.max() << std::endl; std::cout << "- values: " << d(e) << ' ' << d(e) << ' '<< d(e) << ' ' << d(e) << std::endl; // count the generated values (converted to integral values)std::map<long long,int> valuecounter;for (int i=0; i<200000; ++i) {valuecounter[d(e)]++;}// and print the resulting distributionstd::cout << "====" << std::endl;for (auto elem : valuecounter) {std::cout << std::setw(3) << elem.first << ": "<< elem.second << std::endl;}std::cout << "====" << std::endl;std::cout << std::endl;
}int main()
{std::knuth_b e;std::uniform_real_distribution<> ud(0, 10);distr(ud,e,"uniform_real_distribution");std::normal_distribution<> nd;distr(nd,e,"normal_distribution");std::exponential_distribution<> ed;distr(ed,e,"exponential_distribution");std::gamma_distribution<> gd;distr(gd,e,"gamma_distribution");
}
输出:
uniform_real_distribution:
- min():  0
- max():  10
- values: 3.83416 9.47764 1.30427 8.30965
====0: 200871: 200572: 198783: 198774: 200055: 201186: 200637: 198868: 200039: 20026
====normal_distribution:
- min():  -1.79769e+308
- max():  1.79769e+308
- values: 0.538967 -0.140331 0.117963 -0.131724
====-4: 9-3: 245-2: 4325-1: 268430: 1369471: 269872: 43773: 2584: 9
====exponential_distribution:
- min():  0
- max():  1.79769e+308
- values: 0.48356 2.95199 0.139753 1.77765
====0: 1263271: 466372: 171183: 62264: 23375: 8656: 3137: 1088: 389: 2210: 611: 212: 1
====gamma_distribution:
- min():  0
- max():  1.79769e+308
- values: 1.21066 0.558526 1.60557 0.117964
====0: 1263151: 464772: 171603: 62714: 24135: 8666: 3277: 1098: 419: 1210: 711: 112: 1
====

5、async()

#include <future>
#include <thread>
#include <chrono>
#include <random>
#include <iostream>
#include <exception>
using namespace std;// 等待随机的时间,打印字符
void doSomething (char c)
{// random-number generator (use c as seed to get different sequences)default_random_engine dre(c);uniform_int_distribution<int> id(10,1000);// loop to print character after a random period of timefor (int i=0; i<10; ++i) {this_thread::sleep_for(chrono::milliseconds(id(dre)));cout.put(c).flush();}
}int main()
{cout << "starting 2 operations asynchronously" << endl;// start two loops in the background printing characters . or +// 多线程环境下,两个线程会被启动,当然也有可能两个都不会被启动auto f1 = async([]{ doSomething('.'); });auto f2 = async([]{ doSomething('+'); });// if at least one of the background tasks is running// 询问是否至少有一个操作未被推迟if (f1.wait_for(chrono::seconds(0)) != future_status::deferred ||f2.wait_for(chrono::seconds(0)) != future_status::deferred) {// poll until at least one of the loops finished// 询问是否至少有一个操作已经完成,如果都没有完成继续询问while (f1.wait_for(chrono::seconds(0)) != future_status::ready &&f2.wait_for(chrono::seconds(0)) != future_status::ready) {//...;// 两个线程都没有完成,切换到另外的线程this_thread::yield();  // hint to reschedule to the next thread}}cout.put('\n').flush();// wait for all loops to be finished and process any exceptiontry {f1.get();f2.get();}catch (const exception& e) {cout << "\nEXCEPTION: " << e.what() << endl;}cout << "\ndone" << endl;
}
输出:
starting 2 operations asynchronously
+..+..+...+..+.
+++++
done

6、shared_future()

#include <future>
#include <thread>
#include <iostream>
#include <exception>
#include <stdexcept>
using namespace std;int queryNumber ()
{// read numbercout << "read number: ";int num;cin >> num; // throw exception if noneif (!cin) {throw runtime_error("no number read");}return num;
}void doSomething (char c, shared_future<int> f)
{try {// wait for number of characters to printint num = f.get();  // get result of queryNumber()for (int i=0; i<num; ++i) {this_thread::sleep_for(chrono::milliseconds(100));cout.put(c).flush();}}catch (const exception& e) {cerr << "EXCEPTION in thread " << this_thread::get_id()<< ": " << e.what() << endl;}
}int main()
{try {// start one thread to query a number// 这里使用了shared_future,在下面的三个线程中多次调用,都能拿到相同的结果shared_future<int> f = async(queryNumber);// start three threads each processing this number in a loopauto f1 = async(launch::async,doSomething,'.',f);auto f2 = async(launch::async,doSomething,'+',f);auto f3 = async(launch::async,doSomething,'*',f);// wait for all loops to be finishedf1.get();f2.get();f3.get();}catch (const exception& e) {cout << "\nEXCEPTION: " << e.what() << endl;}cout << "\ndone" << endl;
}
输入:7
.+**+..+*+*.+*..*+*+.
done
输入:x
EXCEPTION in thread EXCEPTION in thread 5: EXCEPTION in thread 4: no number read
3: no number read
no number readdone

7、thread()

#include <thread>
#include <chrono>
#include <random>
#include <iostream>
#include <exception>
using namespace std;void doSomething (int num, char c)
{try {// random-number generator (use c as seed to get different sequences)default_random_engine dre(42*c);uniform_int_distribution<int> id(10,1000);for (int i=0; i<num; ++i) {this_thread::sleep_for(chrono::milliseconds(id(dre)));cout.put(c).flush();//...}}// make sure no exception leaves the thread and terminates the programcatch (const exception& e) {cerr << "THREAD-EXCEPTION (thread "<< this_thread::get_id() << "): " << e.what() << endl;}catch (...) {cerr << "THREAD-EXCEPTION (thread "<< this_thread::get_id() << ")" << endl;}
}int main()
{try {thread t1(doSomething,5,'.');  // print five dots in separate threadcout << "- started fg thread " << t1.get_id() << endl;// print other characters in other background threadsfor (int i=0; i<5; ++i) {thread t(doSomething,10,'a'+i); // print 10 chars in separate threadcout << "- detach started bg thread " << t.get_id() << endl;t.detach();  // detach thread into the background}cin.get();  // wait for any input (return)cout << "- join fg thread " << t1.get_id() << endl;t1.join();  // wait for t1 to finish}catch (const exception& e) {cerr << "EXCEPTION: " << e.what() << endl;}
}

8、promise()

#include <thread>
#include <future>
#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>
#include <functional>
#include <utility>void doSomething (std::promise<std::string>& p)
{try {// read character and throw exception if 'x'std::cout << "read char ('x' for exception): ";char c = std::cin.get();if (c == 'x') {throw std::runtime_error(std::string("char ")+c+" read");}//...std::string s = std::string("char ") + c + " processed";p.set_value_at_thread_exit(std::move(s));    // store result}catch (...) {p.set_exception_at_thread_exit(std::current_exception());  // store exception}
}int main()
{try {// create a promise to store the outcomestd::promise<std::string> p;// create a future to process the outcomestd::future<std::string> f(p.get_future());// start a thread using the promise to store the outcomestd::thread t(doSomething,std::ref(p));t.detach();//...// process the outcomestd::cout << "result: " << f.get() << std::endl;}catch (const std::exception& e) {std::cerr << "EXCEPTION: " << e.what() << std::endl;}catch (...) {std::cerr << "EXCEPTION " << std::endl;}
}
输出:
result: read char ('x' for exception): 2
char 2 processed
result: read char ('x' for exception): x
EXCEPTION: char x read 

 9、packaged_task<>操作

 10、unique_lock

std::unique_lock 是 C++ 标准库中的一个锁管理工具,它提供了对互斥量(std::mutex)的更灵活的管理和使用方式。std::unique_lock 具有比 std::lock_guard 更多的特性,例如支持延迟锁定和手动解锁,使其在一些复杂的情境下更为适用。

 (1)构造函数
std::unique_lock<std::mutex> lock(mutex);

传递mutex互斥量,unique_lock对象会立即锁定互斥量。

(2)延迟锁定

std::lock_guard 不同,std::unique_lock 可以在构造时选择是否立即锁定互斥量。可以通过构造函数的第二个参数 std::defer_lock 来实现延迟锁定。

std::unique_lock<std::mutex> lock(mutex, std::defer_lock);
//这里互斥量并未锁定
...
lock.lock();  //手动锁定互斥量
(3)手动解锁

std::lock_guard 不同,std::unique_lock 允许在需要的时候手动解锁互斥量,然后再次锁定。

std::unique_lock<std::mutex> lock(mutex);
//...
lock.unlock();  //手动解锁
//...
lock.lock();  //手动锁定
(4)条件变量

std::unique_lock 提供了与条件变量一起使用的特性,可以在等待条件满足时自动释放锁,以及在条件不满足时重新获取锁。

std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock, [](){return condition;});
(5)锁定多个互斥量

std::unique_lock 允许锁定多个互斥量,以防止死锁。可以在构造函数中传递多个互斥量,并使用 std::lock 来避免死锁。

std::mutex mutex1, mutex2;
std::unique_lock<std::mutex> lock1(mutex1, std::defer_lock);
std::unique_lock<std::mutex> lock2(mutex2, std::defer_lock);
std::lock(lock1, lock2);

11、mutex和lock

 12、condition variable

#include <condition_variable>
#include <mutex>
#include <future>
#include <thread>
#include <iostream>
#include <queue>std::queue<int> queue;
std::mutex queueMutex;
std::condition_variable queueCondVar;void provider (int val)
{// push different values (val til val+5 with timeouts of val milliseconds into the queuefor (int i=0; i<6; ++i) {{std::lock_guard<std::mutex> lg(queueMutex);queue.push(val+i);} // release lockqueueCondVar.notify_one();std::this_thread::sleep_for(std::chrono::milliseconds(val));}
}void consumer (int num)
{// pop values if available (num identifies the consumer)while (true) {int val;{std::unique_lock<std::mutex> ul(queueMutex);queueCondVar.wait(ul,[]{ return !queue.empty(); });val = queue.front();queue.pop();} // release lockstd::cout << "consumer " << num << ": " << val << std::endl;}
}int main()
{// start three providers for values 100+, 300+, and 500+auto p1 = std::async(std::launch::async,provider,100);auto p2 = std::async(std::launch::async,provider,300);auto p3 = std::async(std::launch::async,provider,500);// start two consumers printing the valuesauto c1 = std::async(std::launch::async,consumer,1);auto c2 = std::async(std::launch::async,consumer,2);
}

 所有的notify_one()和notify_all()都会被自动同步化,所以他们的调用不需要放在加锁代码块里面。所有等待某个condition variable的线程都必须使用相同的mutex,当wait()家族的某个成员被调用时,该mutex必须被unique_lock锁定,否则会发生不明确的行为。

注意:condition variable的消费者总是在“被锁住的mutex”基础上操作,只有等待函数会执行以下三个atomic步骤暂时解除mutex:1.解除mutex然后进入等待状态,2.解除因等待而造成的阻塞。3.再次锁住mutex。

13、atomic

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/288753.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 多维数组详解(numpy)

文章目录 1 概述1.1 numpy 简介1.2 ndarray 简介 2 数组操作2.1 创建数组&#xff1a;array()2.2 裁切数组&#xff1a;切片2.3 拼接数组&#xff1a;concatenate()2.4 拆分数组&#xff1a;array_split()2.5 改变数组形状&#xff1a;reshape() 3 元素操作3.1 获取元素&#x…

飞天使-k8s知识点1-kubernetes架构简述

文章目录 名词功能要点 k8s核心要素CNCF 云原生框架简介k8s组建介绍 名词 CI 持续集成, 自动化构建和测试&#xff1a;通过使用自动化构建工具和自动化测试套件&#xff0c;持续集成可以帮助开发人员自动构建和测试他们的代码。这样可以快速检测到潜在的问题&#xff0c;并及早…

【QT】解决QTableView修改合并单元格内容无法修改到合并范围内的单元格

问题:修改合并单元格的内容 修改合并单元格的内容时,希望直接修改到合并范围内的单元格,Qt没有实现这个功能,需要自己写出 Delegate来实现 方案:Delegate class EditDelegate : public QStyledItemDelegate {public:EditDelegate(QTableView *view): tableView(view){}pu…

位操作符详解(C语言)

前言 C语言中的位操作符是用来对数据的二进制表示进行位级操作的运算符。这些操作符包括位与&#xff08;&&#xff09;、位或&#xff08;|&#xff09;、位异或&#xff08;^&#xff09;、位取反&#xff08;~&#xff09;&#xff0c;这些位操作符可以用来进行各种位级…

华为选择“力图生存”!国家队正式出手,外媒:鸿蒙将全面爆发

引言 在国际舞台上&#xff0c;国与国之间的关系错综复杂&#xff0c;舆论的力量也十分重要。近日&#xff0c;关于华为鸿蒙系统失去用户的预测成为热议的话题。这背后所面对的挑战和对抗也异常严峻。本文将解释鸿蒙系统的崛起与前景展望&#xff0c;揭示其中的机遇与挑战。 …

9ACL访问控制列表

为什么要有访问控制&#xff08;Access Control List&#xff09;&#xff1f; 因为我可能在局域网中提供了一些服务&#xff0c;我只希望合法的用户可以访问&#xff0c;其他非授权用户不能访问。 原理比较简单&#xff0c;通过对数据包里的信息做过滤&#xff0c;实现访问控…

《每天一分钟学习C语言·三》

1、 scanf的返回值由后面的参数决定scanf(“%d%d”,& a, &b); 如果a和b都被成功读入&#xff0c;那么scanf的返回值就是2如果只有a被成功读入&#xff0c;返回值为1如果a和b都未被成功读入&#xff0c;返回值为0 如果遇到错误或遇到end of file&#xff0c;返回值为EOF…

华清远见作业第十三天

1.使用多文件编辑&#xff0c; 定义商品信息:商品名称&#xff0c;商品单价&#xff0c;商品购买个数&#xff0c;商品描述&#xff0c;循环输入购买的商品&#xff0c;按单价排序&#xff0c;输出商品信息&#xff0c;计算最贵的商品以及一共花了多少钱? 在create函数&#x…

【科技前沿】数字孪生技术改革智慧供热,换热站3D可视化引领未来

换热站作为供热系统不可或缺的一部分&#xff0c;其能源消耗对城市环保至关重要。在双碳目标下&#xff0c;供热企业可通过搭建智慧供热系统&#xff0c;实现供热方式的低碳、高效、智能化&#xff0c;从而减少碳排放和能源浪费。通过应用物联网、大数据等高新技术&#xff0c;…

C : DS二叉排序树之删除

Description 给出一个数据序列&#xff0c;建立二叉排序树&#xff0c;并实现删除功能 对二叉排序树进行中序遍历&#xff0c;可以得到有序的数据序列 Input 第一行输入t&#xff0c;表示有t个数据序列 第二行输入n&#xff0c;表示首个序列包含n个数据 第三行输入n个数据…

vue-springboot-java电力员工安全施工培训课程考试管理系统

本电力员工安全施工培训管理系统是为了提高员工查阅信息的效率和管理人员管理信息的工作效率&#xff0c;可以快速存储大量数据&#xff0c;还有信息检索功能&#xff0c;这大大的满足了员工和管理员这二者的需求。操作简单易懂&#xff0c;合理分析各个模块的功能&#xff0c;…

Ubuntu 常用命令之 zip 命令用法介绍

Ubuntu系统下的zip命令是用来压缩文件的。这个命令可以将一个或多个文件或者目录压缩成一个.zip文件&#xff0c;也可以将整个目录树压缩成一个.zip文件。 zip命令的基本格式 zip [选项] [压缩文件名] [要压缩的文件或目录...]zip命令的主要参数有 -r&#xff1a;递归压缩&a…