C++11 多线程相关知识的学习

C++多线程类Thread(C++11)

  • C++11中std命名空间将Boost库中的Thread加入,Boost的多线程从准标准变为标准,这里将其用法整理复习,以demo的形式复习,还是喜欢看我自己写的东西,符合我的个人逻辑
  • 头文件为#include<thread>,通过std::thread应用。就以Hello thread开始吧,需要注意的是1,join()函数和detach()函数的区别,2,数据同步操作mutex(需包含include<mutex>):互斥锁

1、  普通函数多线程调用

(1)无参数函数

#include <thread>
#include <iostream>void hello_thread() {std::cout << "Hello Thread!" << std::endl;
}int main() {std::thread t1(hello_thread);  t1.join();  // 主线程等待子线程执行结束之后,才会执行下一步的操作std::cout << "Main here" << std::endl;getchar();return 0;
}

(2)有参数函数

#include <thread>
#include <iostream>using namespace std;int msum(int a, int b) {int c = a + b;cout << a << " + " << b << " = " << c << endl;return c;
}int main() {std::thread t1(msum,1,2);t1.join();  // 主线程等待子线程执行结束之后,才会执行下一步的操作std::cout << "Main here" << std::endl;getchar();return 0;
}

2、在类内部创建线程

(1)类内部函数为静态函数

#include <thread>
#include <iostream>using namespace std;class HelloThread{public:static void hellothread(){cout << "Hello World, I‘m a thread " << endl;}static void start(){thread thread(hellothread);thread.join();}};int main(){HelloThread::start();getchar();return 0;
}
  • 在这里start()和hellothread()方法都必须是static方法。 

(2)在Singleton模式内部创建线程: 

3 、用类内部函数在类外部创建线程:

  • 非常普通的类,只是用多线程调用其内部的函数
#include <thread>
#include <iostream>using namespace std;class HelloWorld{public:void hello(int year){cout << "I am " << year << " years old!" << endl;}
};int main(){HelloWorld obj;thread thrd(&HelloWorld::hello,&obj,26);thrd.join();getchar();return 0;
}

 join()和detach()的区别:

  • join()的作用前面已经提到,主线程等待子线程结束方可执行下一步(串行),detach()是的子线程放飞自我,独立于主线程并发执行,主线程后续代码段无需等待。看看效果:

(1)join()

#include <thread>
#include <iostream>using namespace std;void hello_thread() {std::cout << "Hello Thread!" << std::endl;
}int msum(int a, int b) {int c = a + b;cout << a << " + " << b << " = " << c << endl;return c;
}int main(){thread t1(hello_thread);//主线程等待子线程运行结束之后才可以执行下一步t1.join();thread t2(msum,2,3);t2.join();//主线程代码cout << "Main here " << endl;getchar();return 0;
}

(2)detach()

#include <thread>
#include <iostream>using namespace std;void hello_thread() {std::cout << "Hello Thread!" << std::endl;
}int msum(int a, int b) {int c = a + b;cout << a << " + " << b << " = " << c << endl;return c;
}int main(){thread t1(hello_thread);//主线程等待子线程运行结束之后才可以执行下一步t1.detach();thread t2(msum,2,3);t2.detach();//主线程代码cout << "Main here " << endl;getchar();return 0;
}

 数据同步(线程同时操作一个数据的安全性):

  • 执行单个线程,上锁、解锁,维护了线程的安全性,防止线程之间交叉执行

#include <thread>
#include <iostream>
#include <mutex>
using namespace std;
std::mutex mt;
int data1 = 1;void addmethod(int a){mt.lock();data1 += a;cout << "add data = " << data1 << endl;mt.unlock();
}
void multi(int a){mt.lock();data1 *= a;cout << "multi data = " << data1 << endl;mt.unlock();
}
void hello_thread() {std::cout << "Hello Thread!" << std::endl;
}int msum(int a, int b) {int c = a + b;cout << a << " + " << b << " = " << c << endl;return c;
}int main(){thread t1(addmethod,2);thread t2(multi,2);t1.detach();t2.detach();getchar();return 0;
}

线程暂停

  • 从外部让线程暂停,会引发很多并发问题,此处不做引申。这大概也是std::thread并没有直接提供pause函数的原因。但有时线程在运行时,确实需要“停顿”一段时间怎么办呢?可以使用std::this_thread::sleep_for或std::this_thread::sleep_until
#include <thread>
#include <iostream>
#include <mutex>
#include <chrono>
#include <ratio>
using namespace std;
std::mutex mt;void pausable(){//sleep 500毫秒this_thread::sleep_for(chrono::milliseconds(500));//sleep 到达指定的时间点this_thread::sleep_until(chrono::system_clock::now() + chrono::milliseconds(500));
}
int main(){std::thread thread1(pausable);thread1.join();return 0;
}

线程停止

  • 一般情况下当线程函数执行完成后,线程“自然”停止。但在std::thread中有一种情况会造成线程异常终止,那就是:析构。当std::thread实例析构时,如果线程还在运行,则线程会被强行终止掉,这可能会造成资源的泄漏,因此尽量在析构前join一下,以确保线程成功结束。
  • 如果确实想提前让线程结束怎么办呢?一个简单的方法是使用“共享变量”,线程定期地去检测该量,如果需要退出,则停止执行,退出线程函数。使用“共享变量”需要注意,在多核、多CPU的情况下需要使用“原子”操作。

参考链接

  • https://blog.csdn.net/ouyangfushu/article/details/80199140

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

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

相关文章

C++11 explicit关键字的作用

explicit 在C中&#xff0c;explicit关键字用来修饰类的构造函数&#xff0c;被修饰的构造函数的类&#xff0c;不能发生相应的隐式类型转换&#xff0c;只能以显示的方式进行类型转换。因为无参构造函数和多参构造函数本身就是显示调用的。再加上explicit关键字也没有什么意义…

C++11学习 virtual(虚函数)的用法

Virtual虚函数 在面向对象的C语言中&#xff0c;虚函数&#xff08;virtual function&#xff09;是一个非常重要的概念。因为它充分体现了面向对象思想中的继承和多态性这两大特性&#xff0c;在C语言里应用极广。多态性&#xff1a;其含义就是多种形式&#xff1b;将具有继承…

c++ const

函数名称不单单是函数名 const 补充内容 还有 const 参数类型 函数后头const 只能在成员函数如果const对象 但是我没通过const成员函数 就会报错

手撕源码 alloc

怎么有效的手撕代码呢&#xff1f; gnu gcc 2.9 的 内存池 把代码跑起来把代码一个片段拿出来使用画出代码运行的流程图一行一行的搬运在看源码的情况下写出类似的demo 第三步&#xff1a; 第五步: // 这个头文件包含一个模板类 allocator&#xff0c;用于管理内存的分配、…

针对Algorand所使用的密码相关技术细节进行介绍

关键概念 VRF: 可验证随机函数。简单来说是&#xff1a;vrf,Proof VRF(sk,seed)&#xff0c;sk为私钥&#xff0c;seed为随机种子&#xff1b;通过Verify(proof,pk,seed)验证vrf的合法性。cryptographic sorition: 根据用户本轮的VRF值&#xff0c;自身的权重以及公开的区块链…

对于Algorand的介绍

介绍 Algorand具有能耗低、效率高、民主化、分叉概率极低、可拓展性好等优点&#xff0c;旨在解决现有区块链项目存在的“不可能三角”&#xff08;高度可扩展的、安全的、去中心化&#xff09;问题。Algorand由MIT教授、图灵奖得主Silvio Micali发起&#xff0c;拥有MIT区块链…

C++学习 高级编程

C 文件和流 到目前为止&#xff0c;目前使用最为广泛的是 iostream 标准库&#xff0c;它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流。以下将介绍从文件读取流和向文件写入流。这就需要用到 C 中另一个标准库 fstream&#xff0c;它定义了三个新的数…

内存池中的嵌入式指针

嵌入式指针 可以union改struct 内存分配后 next指针就没用了 直接作为数据空间比较省内存 因为对指针指向的内存存储的时候 编译器是不管你是什么类型的 &#xff0c;这里有道练习题可以对指针的概念稍微理解一下&#xff1a; #include <iostream> using std::cout; us…

内存池的实现4 alloc内存池

alloc 内存池 优点: &#xff1a;本质是定长内存池的改进&#xff0c;分配和释放的效率高。可以解决一定长度内存分配的问题。 缺点 &#xff1a;存在内碎片的问题&#xff0c;且将一块大内存切小以后&#xff0c;申请大内存无法使用&#xff0c;别的FreeList挂了很多空闲的内存…

c语音的一些特殊关键字

PRETTY_FUNCTION C语言中获取函数名 C语言中的__LINE__用以指示本行语句在源文件中的位置信息

vim 不常见但好用的命令

● 跳跃 ○ 向前跳跃是 f ○ 向后跳跃是 F ● 继续 ○ 保持方向是 ; ○ 改变方向是 , ● 可以加上 [count] 来加速 ● ^ 是到本行第一个非空字符 ● 0 是到本行第一个字符&#xff0c;不管是不是空格 ● g_ 是到本行最后一个非空字符 ● 两个按键要依次按下 ● $ 跳到本行最后…

加密机组会 会议纪要

2020年9月28日 1&#xff0c;使用基类继承的机制&#xff0c;调用写好的函数接口 1&#xff0c;不要 使用Content&#xff08;封装数据&#xff0c;本质是一个json字符串&#xff09;&#xff0c;1&#xff0c;因为每次使用这个需要对里面的内容进行序列化&#xff0c;转化成…

演示IPFS的一个完整的流程以及针对部分概念的详解

整体的流程 1&#xff0c;创建ipfs节点 通过ipfs init在本地计算机建立一个IPFS节点本文有些命令已经执行过了&#xff0c;就没有重新初始化。部分图片拷贝自先前文档&#xff0c;具体信息应以实物为准 $ ipfs init initializing IPFS node at /Users/CHY/.ipfs generating 2…

TDengine安装教程

TDengine安装教程 前言 TDengine的安装十分简单&#xff0c;可以有以下三种安装方式&#xff0c;源码安装、通过Docker容器进行安装、通过安装包进行安装。但是使用源码安装较为复杂&#xff0c;通过docker的方式最为简单&#xff0c;但是需要一定docker相关的知识&#xff0…

android 软件首次运行时引导页左右滑动效果

很多手机软件在安装后首次运行都会进入到引导页面&#xff0c;再次运行时会进入到主页面。 多了不说了&#xff0c;先看效果图&#xff1a; 代码如下&#xff1a; main.xml <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:an…

dex分包之--------multidex包的配置使用

目录&#xff1a;一、前言二、产生原因三、MultiDex的简要原理四、MultiDex的使用 一、前言 首先说一下我遇到的情况&#xff0c;最近接手了一个项目是在已有的项目里进行更新添加一些功能&#xff0c;然后该项目导了N多的包&#xff0c;在我使用Android Studio的run”App”直…

Android Studio打包和引用aar

一、简介 Android 库在结构上与 Android 应用模块相同。它可以提供构建应用所需的一切内容&#xff0c;包括源代码、资源文件和 Android 清单。不过&#xff0c;Android 库将编译到您可以用作 Android 应用模块依赖项的 Android 归档 (AAR) 文件&#xff0c;而不是在设备上运行…

C++有限状态机的实现

//待完善 有限状态机是一个很常用的技术&#xff0c;在流程控制和游戏AI中都比较实用&#xff0c;因为状态机编程简单又很符合直觉。与有限状态机类似的是设计模式中的状态模式。本文是参考《Programming Game AI by Example》 一、 记得最开始工作时候也接触过有限状态机&…

C++ unsigned char*转化为string的形式

unsigned char*转化为string int main(int argc,char **argv){//unsigned char * 转化为string//参考链接 https://www.itdaan.com/tw/4ff531a5e6651468a5b7c6d95927ba3dunsigned char *foo;unsigned char str[] "Hello world";string strHH;foo str;strHH.append…