当前位置: 首页 > news >正文

台州网站建设咨询搜索引擎网络排名

台州网站建设咨询,搜索引擎网络排名,wordpress后太慢,产品营销方案C11学习 一、多线程 1、模板线程是以右值传递的 template class Fn, class... Args explicit thread(Fn fn, Args... args)则需要使用到std::ref和std::cref很好地解决了这个问题#xff0c;std::ref 可以包装按引用传递的值。 std::cref 可以…C11学习 一、多线程 1、模板线程是以右值传递的 template class Fn, class... Args explicit thread(Fn fn, Args... args)则需要使用到std::ref和std::cref很好地解决了这个问题std::ref 可以包装按引用传递的值。 std::cref 可以包装按const引用传递的值。 // Compiler: MSVC 19.29.30038.1 // C Standard: C17 #include iostream #include thread using namespace std; templateclass T void changevalue(T x, T val) {x val; } int main() {thread th[100];int nums[100];for (int i 0; i 100; i)th[i] thread(changevalueint, ref(nums[i]), i1);for (int i 0; i 100; i) {th[i].join();cout nums[i] endl;}return 0; } 2、线程一些注意事项 线程是在thread对象被定义的时候开始执行的而不是在调用join函数时才执行的调用join函数只是阻塞等待线程结束并回收资源。 分离的线程执行过detach的线程会在调用它的线程结束或自己结束时释放资源。 线程会在函数运行完毕后自动释放不推荐利用其他方法强制结束线程可能会因资源未释放而导致内存泄漏。 没有执行join或detach的线程在程序结束时会引发异常 3、std::mutex互斥锁 三个方法 lock 上锁 unlock 解锁 bool try_lock() 尝试将mutex上锁。如果mutex未被上锁则将其上锁并返回true如果mutex已被锁则返回false。4、std::atomic atomic_flag 意思是该类型的变量是原子类型的操作。因为mutex的资源浪费较大总是要上锁解锁的。引入atomic std::atomic_int只是std::atomicint atomic_int n 0; 表示定义一个int类型的原子属性的变量n他是线程安全的atomic() noexcept default默认构造函数构造一个atomic对象未初始化可通过atomic_init进行初始化constexpr atomic(T val) noexcept初始化构造函数构造一个atomic对象用val的值来初始化 atomic_flag原子布尔类型不同于 std::atomic std::atomic_flag 不提供加载或存储操作。 成员函数 (构造函数)构造 atomic_flag (公开成员函数)operator赋值运算符 (公开成员函数)clear原子地设置标志为 false (公开成员函数)test_and_set原子地设置标志为 true 并获得其先前值 (公开成员函数) #include thread #include vector #include iostream #include atomic//ATOMIC_FLAG_INIT 置为false std::atomic_flag lock ATOMIC_FLAG_INIT;void f(int n) {for (int cnt 0; cnt 100; cnt) {//std::memory_order_acquire 内存访问while (lock.test_and_set(std::memory_order_acquire)) // 获得锁; // 自旋std::cout Output from thread n \n;lock.clear(std::memory_order_release); // 释放锁} }int main() {std::vectorstd::thread v;for (int n 0; n 10; n) {v.emplace_back(f, n);}for (auto t : v) {t.join();} }5、std::asyncstd::futurestd::shared_future std::async定义在future头文件中新的线程类执行效率更高于thread并且可以选择同步异步执行还有返回值可以选择调用时间。 重载版本作用template class Fn, class… Args futuretypename result_ofFn(Args…)::type async (Fn fn, Args… args)异步或同步根据操作系统而定以args为参数执行fn同样地传递引用参数需要std::ref或std::creftemplate class Fn, class… Args futuretypename result_ofFn(Args…)::type async (launch policy, Fn fn, Args… args);异步或同步根据policy参数而定见下文以args为参数执行fn引用参数同上。std::launch有2个枚举值和1个特殊值枚举值launch::async、launch::deferred、launch::async // Compiler: MSVC 19.29.30038.1 // C Standard: C17 #include iostream #include thread #include future using namespace std; int main() {async(launch::async, [](const char *message){cout message flush;}, Hello, );cout World! endl;return 0; }其async的返回值std::future是一个模板对象。 其成员函数有 一般T get()当类型为引用R futureR::get()当类型为voidvoid future::get()阻塞等待线程结束并获取返回值。若类型为void则与future::wait()相同。只能调用一次。void wait() const阻塞等待线程结束template class Rep, class Period future_status wait_for(const chrono::durationRep,Period rel_time) const;阻塞等待rel_timerel_time是一段时间若在这段时间内线程结束则返回future_status::ready若没结束则返回future_status::timeout若async是以launch::deferred启动的则不会阻塞并立即返回future_status::deferred std::future的作用并不只有获取返回值它还可以检测线程是否已结束、阻塞等待所以对于返回值是void的线程来说future也同样重要。 // Compiler: MSVC 19.29.30038.1 // C Standard: C17 #include iostream #include future using namespace std; void count_big_number() {// C14标准中可以在数字中间加上单// 引号 来分隔数字使其可读性更强for (int i 0; i 1000000000; i); } int main() {futurevoid fut async(launch::async, count_big_number);cout Please wait flush;// 每次等待1秒while (fut.wait_for(chrono::seconds(1)) ! future_status::ready)cout . flush;cout endl Finished! endl;return 0; } std::shared_future类模板 std::shared_future 提供访问异步操作结果的机制类似 std::future 除了允许多个线程等候同一共享状态。不同于仅可移动的 std::future 故只有一个实例能指代任何特定的异步结果std::shared_future 可复制而且多个 shared_future 对象能指代同一共享状态。 若每个线程通过其自身的 shared_future 对象副本访问则从多个线程访问同一共享状态是安全的。 #include iostream #include future #include chronoint main() { std::promisevoid ready_promise, t1_ready_promise, t2_ready_promise;std::shared_futurevoid ready_future(ready_promise.get_future());std::chrono::time_pointstd::chrono::high_resolution_clock start;auto fun1 [, ready_future]() - std::chrono::durationdouble, std::milli {t1_ready_promise.set_value();ready_future.wait(); // 等待来自 main() 的信号return std::chrono::high_resolution_clock::now() - start;};auto fun2 [, ready_future]() - std::chrono::durationdouble, std::milli {t2_ready_promise.set_value();ready_future.wait(); // 等待来自 main() 的信号return std::chrono::high_resolution_clock::now() - start;};auto result1 std::async(std::launch::async, fun1);auto result2 std::async(std::launch::async, fun2);// 等待线程变为就绪t1_ready_promise.get_future().wait();t2_ready_promise.get_future().wait();// 线程已就绪开始时钟start std::chrono::high_resolution_clock::now();// 向线程发信使之运行ready_promise.set_value();std::cout Thread 1 received the signal result1.get().count() ms after start\n Thread 2 received the signal result2.get().count() ms after start\n; }6、std::promise 是实际上是std::future的一个包装但是作用确实想实现线程函数的左值引用将函数执行结果带回来。 一般void set_value (const T val)void set_value (T val)当类型为引用void promiseR::set_value (R val)当类型为voidvoid promise::set_value (void)设置promise的值并将共享状态设为ready将future_status设为readyvoid特化只将共享状态设为readyfuture get_future()构造一个future对象其值与promise相同status也与promise相同 // Compiler: MSVC 19.29.30038.1 // C Standard: C17 #include iostream #include thread #include future // std::promise std::future using namespace std;templateclass ... Args decltype(auto) sum(Args... args) {return (0 ... args); }templateclass ... Args void sum_thread(promiselong long val, Args... args) {val.set_value(sum(args...)); //设置值 }int main() {promiselong long sum_value;//目的还是传递左值引用thread get_sum(sum_threadint, int, int, ref(sum_value), 1, 10, 100);cout sum_value.get_future().get() endl; //获取值get_sum.join(); // 感谢评论区 未来想做游戏 的提醒return 0; } 6、std::this_thread中的一些静态方法 std::thread::id get_id() noexcept获取当前线程idtemplateclass Rep, class Periodvoid sleep_for( const std::chrono::durationRep, Period sleep_duration )等待sleep_durationsleep_duration是一段时间void yield() noexcept暂时放弃线程的执行将主动权交给其他线程放心主动权还会回来template class Clock, class Duration void sleep_until (const chrono::time_pointClock,Duration abs_time);等到到abs_time这个时间到来再执行 #include iostream #include thread #include atomic using namespace std; atomic_bool ready 0; //原子类型变量 bool类型 atomicbool // uintmax_t unsigned long long void sleep(uintmax_t ms) {this_thread::sleep_for(chrono::milliseconds(ms)); } void count() {while (!ready) this_thread::yield();//暂时交出cpu执行for (int i 0; i 2000000000; i);cout Thread this_thread::get_id() finished! endl;return; } int main() {thread th[10];for (int i 0; i 10; i)th[i] thread(::count);sleep(5000);ready true;cout Start! endl;for (int i 0; i 10; i)th[i].join();return 0; } // this_thread::sleep_for example #include iostream // std::cout #include iomanip // std::put_time #include thread // std::this_thread::sleep_until #include chrono // std::chrono::system_clock #include ctime // std::time_t, std::tm, std::localtime, std::mktime int main() { using std::chrono::system_clock; std::time_t tt system_clock::to_time_t (system_clock::now()); struct std::tm * ptm std::localtime(tt); std::cout Current time: std::put_time(ptm,%X) \n; std::cout Waiting for the next minute to begin...\n; ptm-tm_min; ptm-tm_sec0; std::this_thread::sleep_until (system_clock::from_time_t (mktime(ptm))); std::cout std::put_time(ptm,%X) reached!\n; return 0; }7、std::lock_guard std::unique_lock 成员函数 (构造函数)构造 lock_guard 可选地锁定给定的互斥 (公开成员函数)(析构函数)析构 lock_guard 对象解锁底层互斥 (公开成员函数) lock_guard( mutex_type m, std::adopt_lock_t t );的构造方法的第二个参数 std::defer_lock_t, std::try_to_lock_t, std::adopt_lock_t 三个值。是用于为 std::lock_guard 、 std::scoped_lock 、 std::unique_lock 和 std::shared_lock 指定锁定策略的空类标签类型。 defer_lock_t不获得互斥的所有权try_to_lock_t尝试获得互斥的所有权而不阻塞adopt_lock_t假设调用方线程已拥有互斥的所有权 构造互斥锁的写法就是会在lock_guard构造函数里加锁在析构函数里解锁达到自动加锁解锁的目的。因此lock_guard的作用域就是锁的范围。 #include iostream #include thread #include string #include mutex using namespace std;mutex mt; void thread_task() {for (int i 0; i 10; i){lock_guardmutex guard(mt);cout print thread: i endl;} }int main() {thread t(thread_task);for (int i 0; i -10; i--){lock_guardmutex guard(mt);cout print main: i endl;}t.join();return 0; }虽然lock_guard挺好用的但是有个很大的缺陷在定义lock_guard的地方会调用构造函数加锁在离开定义域的话lock_guard就会被销毁调用析构函数解锁。这就产生了一个问题如果这个定义域范围很大的话那么锁的粒度就很大很大程序上会影响效率。所以为了解决lock_guard锁的粒度过大的原因unique_lock就出现了。 unique_lockmutex unique(mt);这个会在构造函数加锁然后可以利用unique.unlock()来解锁所以当你觉得锁的粒度太多的时候可以利用这个来解锁而析构的时候会判断当前锁的状态来决定是否解锁如果当前状态已经是解锁状态了那么就不会再次解锁而如果当前状态是加锁状态就会自动调用unique.unlock()来解锁。而lock_guard在析构的时候一定会解锁也没有中途解锁的功能。方便肯定是有代价的unique_lock内部会维护一个锁的状态所以在效率上肯定会比lock_guard慢。 (构造函数)构造 unique_lock 可选地锁定提供的互斥 (公开成员函数)(析构函数)若占有关联互斥则解锁之 (公开成员函数)operator若占有则解锁互斥并取得另一者的所有权 (公开成员函数)锁定lock锁定关联互斥 (公开成员函数)try_lock尝试锁定关联互斥若互斥不可用则返回 (公开成员函数)try_lock_for试图锁定关联的可定时锁定 (TimedLockable) 互斥若互斥在给定时长中不可用则返回 (公开成员函数)try_lock_until尝试锁定关联可定时锁定 (TimedLockable) 互斥若抵达指定时间点互斥仍不可用则返回 (公开成员函数)unlock解锁关联互斥 (公开成员函数)修改器swap与另一 std::unique_lock 交换状态 (公开成员函数)release将关联互斥解关联而不解锁它 (公开成员函数)观察器mutex返回指向关联互斥的指针 (公开成员函数)owns_lock测试锁是否占有其关联互斥 (公开成员函数)operator bool测试锁是否占有其关联互斥 #include mutex #include thread #include chronostruct Box {explicit Box(int num) : num_things{num} {}int num_things;std::mutex m; };void transfer(Box from, Box to, int num) {// 仍未实际取锁std::unique_lockstd::mutex lock1(from.m, std::defer_lock);std::unique_lockstd::mutex lock2(to.m, std::defer_lock);// 锁两个 unique_lock 而不死锁std::lock(lock1, lock2);from.num_things - num;to.num_things num;// from.m 与 to.m 互斥解锁于 unique_lock 析构函数 }int main() {Box acc1(100);Box acc2(50);std::thread t1(transfer, std::ref(acc1), std::ref(acc2), 10);std::thread t2(transfer, std::ref(acc2), std::ref(acc1), 5);t1.join();t2.join(); }8、condition_variable 条件变量 condition_variable 类是同步原语能用于阻塞一个线程或同时阻塞多个线程直至另一线程修改共享变量条件并通知 condition_variable 。 -------------有意修改变量的线程必须 获得 std::mutex 常通过 std::lock_guard 在保有锁时进行修改 在 std::condition_variable 上执行 notify_one 或 notify_all 不需要为通知保有锁 即使共享变量是原子的也必须在互斥下修改它以正确地发布修改到等待的线程。 -----------任何有意在 std::condition_variable 上等待的线程必须 在与用于保护共享变量者相同的互斥上获得 std::unique_lockstd::mutex 执行下列之一 检查条件是否为已更新或提醒它的情况 执行 wait 、 wait_for 或 wait_until 等待操作自动释放互斥并悬挂线程的执行。 condition_variable 被通知时时限消失或虚假唤醒发生线程被唤醒且自动重获得互斥。之后线程应检查条件若唤醒是虚假的则继续等待。 或者 使用 wait 、 wait_for 及 wait_until 的有谓词重载它们包揽以上三个步骤std::condition_variable 只可与 std::unique_lockstd::mutex 一同使用 成员函数 (构造函数)构造对象 (公开成员函数)(析构函数)析构对象 (公开成员函数)operator[被删除]不可复制赋值 (公开成员函数)通知notify_one通知一个等待的线程 (公开成员函数)notify_all通知所有等待的线程 (公开成员函数)等待wait阻塞当前线程直到条件变量被唤醒 (公开成员函数)wait_for阻塞当前线程直到条件变量被唤醒或到指定时限时长后 (公开成员函数)wait_until阻塞当前线程直到条件变量被唤醒或直到抵达指定时间点 (公开成员函数)原生句柄native_handle返回原生句柄 #include iostream #include string #include thread #include mutex #include condition_variablestd::mutex m; std::condition_variable cv; std::string data; bool ready false; bool processed false;void worker_thread() {// 等待直至 main() 发送数据std::unique_lockstd::mutex lk(m);cv.wait(lk, []{return ready;});//阻塞当前线程直到条件变量被唤醒 (公开成员函数)// 等待后我们占有锁。std::cout Worker thread is processing data\n;data after processing;// 发送数据回 main()processed true;std::cout Worker thread signals data processing completed\n;// 通知前完成手动解锁以避免等待线程才被唤醒就阻塞细节见 notify_one lk.unlock();cv.notify_one(); }int main() {std::thread worker(worker_thread);data Example data;// 发送数据到 worker 线程{std::lock_guardstd::mutex lk(m);ready true;std::cout main() signals data ready for processing\n;}cv.notify_one();// 等候 worker{std::unique_lockstd::mutex lk(m);cv.wait(lk, []{return processed;});}std::cout Back in main(), data data \n;worker.join(); }总结C多线程涉及5个头文件 thread.hthread 类 成员方法thread 构造函数join 等待结束detach 分离线程,则无需等待结束this_thread 命名空间静态方法get_id 获取当前线程idyield 暂时交出cpu执行权sleep_for 睡眠等待函数sleep_until 等待到下一个具体的时间 mutex.hmutex 互斥锁lock_guard 配合互斥锁达到互斥锁作用域范围内的自动上锁解锁unique_lock 在lock_guard基础上加了可以手动解锁的接口unlockatomic.hatomic 原子化变量atomic_flag 原子布尔类型condition_variable.hcondition_variablewait 阻塞当前线程直到条件变量被唤醒 (公开成员函数)wait_for 阻塞当前线程直到条件变量被唤醒或到指定时限时长后 (公开成员函数)wait_until 阻塞当前线程直到条件变量被唤醒或直到抵达指定时间点 (公开成员函数)notify_ont 通知一个等待的线程 (公开成员函数)notify_all 通知所有等待的线程 (公开成员函数)condition_variable_any std::condition_variable 的泛化waitwait_forwait_untilnotify_ontnotify_all future.hfuture 类似一个针对线程的类模板对象可以对线程进行管理的。shared_future 不同于仅可移动的 std::future 故只有一个实例能指代任何特定的异步结果std::shared_future 可复制而且多个 shared_future 对象能指代同一共享状态。promise 类似futurepackaged_task
http://www.dnsts.com.cn/news/248488.html

相关文章:

  • 南通网站制作系统江西响应式网站制作
  • 网页网站关系好网站建设公司开发
  • 八旬老太做直播 什么网站可以做微网站的第三方平台
  • 石家庄网站建设规划百度自助建站官网
  • 把网站内容全删掉 在重新建立会不会被k虚拟主机如何搭建网站
  • 深圳专业网站建设制作网站模块在线制作教程
  • 博客网站 做淘宝客建设工程项目管理
  • 学习做网站的网站公司注册地址变更网上流程怎么办
  • 男做女爱网站山东省建设管理中心网站首页
  • 横翻网站模版长春网站制作企业
  • 网站开发团队人数构成成都建工网站
  • 网站开发流程视频软装设计理念
  • 建筑网站、网站推广与维护设计方案
  • 建设微信商城网站制作众筹网站搭建
  • 网站建设与管理是什么工作阿里云服务器登录入口
  • 青海省建设厅通报网站网络设计方案包括哪些
  • 拖拽做网站网站左侧的导航是怎么做的
  • 网站如何做区域屏蔽代码wordpress 站点网络
  • html购物网站做百度推广的公司电话号码
  • 手机网站申请wordpress使用oss
  • 凡科建的网站可以做seo吗网站建设vs网络推广
  • 找室内效果图的网站建站工具免费
  • 图片上加语音 网站开发万网网站建设选哪个好
  • seo营销型网站济南网站建设团队
  • 网站开发中遇到哪些问题下载应用的app
  • 做模拟人生比较有名的网站学校网站需求
  • 做网站得多钱北京推广网站
  • 重庆网站制作设计263邮箱个人登录入口
  • 加强财政门户网站建设工作变化型网页网站有哪些
  • 猜艺士科技网站建设杭州网站的建设