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

网站建设总经理岗位职责dede 网站地图模板htm

网站建设总经理岗位职责,dede 网站地图模板htm,保洁公司哪家好,河南企业站seo参考引用 C11 14 17 20 多线程从原理到线程池实战代码运行环境:Visual Studio 2019 1. 为什么要用多线程 任务分解 耗时的操作,任务分解,实时响应 数据分解 充分利用多核CPU处理数据 数据流分解 读写分离,解耦合设计 2. 第一个…

参考引用

  • C++11 14 17 20 多线程从原理到线程池实战
  • 代码运行环境:Visual Studio 2019

1. 为什么要用多线程

  • 任务分解
    • 耗时的操作,任务分解,实时响应
  • 数据分解
    • 充分利用多核CPU处理数据
  • 数据流分解
    • 读写分离,解耦合设计

2. 第一个子线程代码示例

  • first_thread.cpp
    #include <iostream>
    #include <thread>using namespace std;// 创建的子线程的入口函数
    void ThreadMain() {// 获取子线程开始时刻的 ID 号cout << "begin sub thread ID " << this_thread::get_id() << endl;for (int i = 0; i < 5; i++) {cout << "in thread " << i << endl;// 子线程睡眠(释放)CPU 资源 1000msthis_thread::sleep_for(chrono::seconds(1));  }cout << "end sub thread ID " << this_thread::get_id() << endl;
    }// 主线程的入口函数 main()
    int main(int argc, char* argv[]) {cout << "main thread ID " << this_thread::get_id() << endl;// 线程创建启动thread th(ThreadMain);cout << "begin wait sub thread" << endl;// 阻塞等待子线程退出th.join();cout << "end wait sub thread" << endl;return 0;
    }
    
  • 控制台输出
    main thread ID 21580
    begin wait sub thread
    begin sub thread ID 22924
    in thread 0
    in thread 1
    in thread 2
    in thread 3
    in thread 4
    end sub thread ID 22924
    end wait sub thread
    

3. std::thread 对象生命周期、线程等待和分离

  • thread_detach.cpp

    #include <iostream>
    #include <thread>using namespace std;bool is_exit = false;void ThreadMain() {cout << "begin sub thread ID " << this_thread::get_id() << endl;for (int i = 0; i < 5; i++) {if (!is_exit)break;cout << "in thread " << i << endl;this_thread::sleep_for(chrono::seconds(1));  // 子线程睡眠(释放)CPU 资源 1000ms}cout << "end sub thread ID " << this_thread::get_id() << endl;
    }int main(int argc, char* argv[]) {{//thread th(ThreadMain); // 出错,thread 对象被销毁 子线程还在运行}{thread th(ThreadMain);th.detach();  // 子线程与主线程分离 守护线程(在后台运行)// 但存在一个问题:主线程退出后 子线程不一定退出}{thread th(ThreadMain);this_thread::sleep_for(chrono::seconds(1));//1000msis_exit = true;  // 通知子线程退出cout << "主线程阻塞,等待子线程退出" << endl;th.join();       // 主线程阻塞,等待子线程退出cout << "子线程已经退出!" << endl;}getchar();return 0;
    }
    
  • 控制台输出

    begin sub thread ID 25520
    end sub thread ID 25520
    begin sub thread ID 23324
    end sub thread ID 23324
    主线程阻塞,等待子线程退出
    子线程已经退出!
    

4. 全局函数作为线程入口

  • thread_para.cpp

    #include <iostream>
    #include <thread>
    #include <string>using namespace std;class Para {
    public:Para() {cout << "Create Para" << endl;}Para(const Para& p) {  // 拷贝构造函数cout << "Copy Para" << endl; }~Para() {cout << "Drop Para" << endl;}string name;
    };void ThreadMain(int p1, float p2, string str, Para p4) {this_thread::sleep_for(100ms);cout << "ThreadMain " << p1 << " " << p2 << " " << str << " " << p4.name << endl;
    }int main(int argc, char* argv[]) {thread th;{float f1 = 12.1f;Para p;p.name = "test Para class";// 所有的参数做复制th = thread(ThreadMain, 101, f1, "test string para", p);}th.join();return 0;
    }
    
  • 控制台输出

    Create Para
    Copy Para
    Drop Para
    Copy Para
    ThreadMain 101 12.1 test string para
    Drop Para
    Drop Para
    

5. 线程函数传递指针和引用

  • 参数传递存在的问题

    • 传递空间已经销毁
    • 多线程共享访问一块空间
    • 传递的指针变量的生命周期小于线程
  • thread_para.cpp

#include <thread>
#include <iostream>
#include <string>using namespace std;class Para {
public:Para() { cout << "Create Para" << endl; }Para(const Para& p) { cout << "Copy Para" << endl; }~Para() { cout << "Drop Para" << endl; }string name;
};void ThreadMain(int p1, float p2, string str, Para p4) {this_thread::sleep_for(100ms);cout << "ThreadMain " << p1 << " " << p2 << " " << str <<" "<<p4.name<< endl;
}void ThreadMainPtr(Para* p) {this_thread::sleep_for(100ms);cout << "ThreadMainPtr name = " << p->name << endl;
}void ThreadMainRef(Para& p) {this_thread::sleep_for(100ms);cout << "ThreadMainPtr name = " << p.name << endl;
}
int main(int argc, char* argv[]) {{// 传递引用Para p;p.name = "test ref";thread th(ThreadMainRef, ref(p));th.join();}getchar();{// 传递线程指针Para p;p.name = "test ThreadMainPtr name";thread th(ThreadMainPtr, &p);  th.detach();  // 错误,线程访问的 p 空间会提前释放}getchar();  // Para 释放{  // 传递线程指针Para p;p.name = "test ThreadMainPtr name";thread th(ThreadMainPtr, &p);th.join();getchar();}thread th;{float f1 = 12.1f;Para p;p.name = "test Para class";// 所有的参数做复制th =  thread(ThreadMain, 101, f1, "test string para", p);}th.join();return 0;
}
  • 控制台输出
    Create Para
    ThreadMainPtr name = test ref
    Drop Para
    

6. 成员函数作为线程入口–封装线程基类接口

  • XThread.h

    • 封装线程基类接口
    #pragma once#include <iostream>
    #include <thread>class XThread {
    public:virtual void Start() {is_exit_ = false;th_ = std::thread(&XThread::Main, this);}virtual void Stop() {is_exit_ = true;Wait();}virtual void Wait() {if (th_.joinable())th_.join();}bool is_exit() {return is_exit_;}private:virtual void Main() = 0;  // 纯虚函数必须要在基类中实现std::thread th_;bool is_exit_ = false;    // 符合谷歌代码风格,私有成员变量后缀加 _
    };
    
  • thread_class.cpp

    #include <iostream>
    #include <thread>
    #include <string>
    #include "XThread.h"using namespace std;/*
    class MyThread {
    public:// 入口线程函数void Main() {cout << "MyThread Main" << name << ": " << age;}string name;int age = 0;
    };
    */class TestXThread : public XThread {
    public:void Main() override {cout << "TestXThread Main begin" << endl;while (!is_exit()) {this_thread::sleep_for(100ms);cout << "." << flush;  // 添加 flush 是为了确保 . 正常输出}cout << "\nTestXThread Main end" << endl;}string name;
    };int main(int argc, char* argv[]) {TestXThread testth;testth.name = "TestXThread name ";testth.Start();this_thread::sleep_for(3s);testth.Stop();testth.Wait();getchar();/*MyThread myth;myth.name = "Test name";myth.age = 20;thread th(&MyThread::Main, &myth);th.join();*/return 0;
    }
    
  • 控制台输出

    TestXThread Main begin
    ............................
    TestXThread Main end
    

7. lambda 临时函数作为线程入口

  • lambda 函数基本格式

    • [捕捉列表] (参数) mutable -> 返回值类型 {函数体}
  • thread_lambda.cpp

    #include <iostream>
    #include <thread>
    #include <string>using namespace std;class TestLambda {
    public:void Start() {thread th([this]() {cout << "name = " << name << endl; });th.join();}string name = "Test Lambda";
    };int main(int argc, char* argv[]) {thread th([](int i) {cout << "test lambda " << i << endl;}, 123);th.join();TestLambda test;test.Start();return 0;
    }
    
  • 控制台输出

    test lambda 123
    name = Test Lambda
    

8. call_once 多线程调用函数只进入一次

初始化函数可以在每一个类型的构造里都调用一遍,不用明确区分,代码可读性提升

  • call_once.cpp

    #include <iostream>
    #include <thread>
    #include <string>
    #include <mutex>using namespace std;void SystemInit() {cout << "Call SystemInit" << endl;
    }void CallOnceSystemInit() {static std::once_flag flag;  // 通过 flag 区分是否只调用一次std::call_once(flag, SystemInit);
    }int main(int argc, char* argv[]) {CallOnceSystemInit();CallOnceSystemInit();for (int i = 0; i < 3; i++) {thread th(CallOnceSystemInit);th.detach();}getchar();return 0;
    }
    
  • 控制台输出

    Call SystemInit
    
http://www.bjxfkj.com.cn/article/110917.html

相关文章:

  • 哪里有建设网站的北京工商注册网官网
  • 网站建设广州公司哪家好文山微网站建设
  • 做韩国网站有哪些东西吗新手做地方门户网站
  • 商标免费设计青岛官网seo推广
  • 南京企业网站设计wordpress媒体库只有2m
  • 做网站销售 优帮云建设局合同备案是哪个网站
  • 南昌市科协网站网站推广人员怎么算业绩
  • 建设部网站防排烟规范上海老闵行网站建设
  • 计算机网站开发参考文献福田公司总部大厦
  • 建设大型网站需要什么硬件网站上传图片不成功
  • 网站策划书背景介绍怎么写营销型网站建站公司
  • 湘潭做网站 就问磐石网络网络推广图片
  • 企业网站的制作网络营销的概念及手段
  • 阿里巴巴网站官网移动论坛网站模板免费下载
  • 哪些网站是jsp做的网站建设中的网页布局主要内容
  • 温州网站开发定制网站网络投票建设步骤
  • 建设小学瓯江小区网站wordpress主题新闻
  • 济南高端网站建设价格wordpress主题:yusi
  • 兰州的网站建设怎建网站
  • 网站数据怎么会丢失福州网龙网络公司
  • 服务器搭建网站跑不满宽带宁夏住房和城乡建设部网站
  • 网站地图百度app手机版
  • 如何查询网站接入商新沂今天重大新闻
  • 哪种语言做网站最快电子商务网站前台建设常用的技术
  • 网站建设后期维护小魔仙做网站app价格多少钱
  • 国外的域名注册网站做58同城网站花了多少钱
  • 哪家网站建设专业建设网站的效益分析
  • 做网站认证对网站有什么好处客户关系管理系统平台
  • 做解析视频网站违法莫大良网站智能推广价格
  • 广东网站开发推荐软件公司招聘网站