【C++】多线程thread

news/2024/7/5 12:15:09

进程和线程这部分呢我之前在我Linux中写过这些东西,和C++中线程的概念差不多,大家可以去看一下:

Linux多线程_神厨小福贵!的博客-CSDN博客进程和线程的区别有哪些呢?进程是资源分配的最小单位,线程是CPU调度的最小单位进程有自己的独立地址空间,线程共享进程中的地址空间进程的创建消耗资源大,线程的创建相对较小进程的切换开销大,线程的切换开销相对较小进程:程序执行的过程叫进程。线程:进程内部的一条执行序列或执行路径,一个进程可以包含多条线程(多线程)!每个进程最少有一个线程,例如下面代码:#include <stdio.h>int main(){ return 0;} ...https://blog.csdn.net/qq_45829112/article/details/121458560

进程和线程的区别:

进程是资源分配的最小单位,线程是CPU调度的最小单位

进程有自己的独立地址空间,线程共享进程中的地址空间

进程的创建消耗资源大,线程的创建相对较小

进程的切换开销大,线程的切换开销相对较小

进程:程序执行的过程叫进程。

线程:进程内部的一条执行序列或执行路径,一个进程可以包含多条线程(多线程)!

每个进程最少有一个线程例如下面代码:

#include <iostream>
using namespace std;int main()
{return 0;
}

虽然只有一个主函数main,主函数的线程又叫主线程,其他的线程都叫它的子线程。

上面看完之后大致明白了线程的进程的区别,下面我们来看一下常用到的函数有哪些:

 上图来自于C++帮助文档:

std::thread - cppreference.comhttps://zh.cppreference.com/w/cpp/thread/thread

先来看第一个构造函数:

打开它的构造函数,我们可以看到:

上图我们可以看到我们在下面这行代码后有个delete,也就是拷贝构造函数被删除了,不可以通过拷贝构造来创建线程!

thread(  const thread& ) = delete;

        我们只能通过缺省构造,移动构造,函数构建和类对象来构建对象!!!

缺省构建:

#include<iostream>
using namespqce std;int main()
{std::thread t1;return 0;
}

值得一提的是,上述t1根本意义上不算是一个线程,原因是构造不表示线程的新 thread 对象, 只是一个空的thread对象,因为没有指定函数指针,所以不会启动一个线程。

移动构造/函数构建:

void f1(int& n)
{n += 10;
}int main()
{int n = 0;std::thread t3(f1, std::ref(n)); //std::ref()将值按引用传递//因为上述函数f1中接收的参数是按照引用来接受的,所以传值引用std::thread t4(std::move(t3)); //std::,ove()将值按照右值传递//在t4创建时,t3就已经不是一个线程了  将t3的资源转移给t4
}

 类对象构建对象:

class foo
{
public:void fun(){cout << "foo::fun run" << endl;}
};int main()
{foo f;thread t5(&foo::fun, &f);t5.join();return 0;
}

joinable函数

先来看下官方的解释:

这玩意主要作用就是检测线程是否为一个可执行线程,可执行返回true,否则返回false 

我们来看下这个函数需要注意的点:

 下面代码来演示:

void foo()
{std::this_thread::sleep_for(std::chrono::seconds(1));
}int main()
{thread t;   //缺省构造的线程std::cout << t.joinable() << endl;t = thread(foo); cout << t.joinable() << endl;t.join();thread t1(std::move(t));   cout << t1.joinable() << endl;std::cout << t.joinable() << endl;//移动之后的的tjoinable为false
}

我们可以看到,t为缺省构造的线程,t1为移动构造的线程,看下面运行结果:

 我们可以看到结果符合我们上图所说到的joinable()函数特点!!!

get_id()函数

我们先来看官方的解释以及返回值!

 下面来看代码演示:

int main()
{thread t1(fun,std::ref(g_max));std::thread::id t1_id = t1.get_id();cout << t1_id << endl;t1.join();return 0;
}

运行结果:

join()函数 

 join()函数的作用就是起到一个阻塞作用直到需要等待的线程返回,才会继续执行下面的代码

直接来看代码演示:

void foo()
{cout << "foo run" << endl;std::this_thread::sleep_for(std::chrono::seconds(10)); //在该线程中阻塞一秒
}void bar()
{cout << "bar run" << endl;std::this_thread::sleep_for(std::chrono::seconds(10)); //在该线程中阻塞一秒
}int main()
{std::thread th1(foo);std::thread th2(bar);std::cout << "waiting for helpers to finish..." << std::endl;th1.join();th2.join();std::cout << "done!\n";
}

在两线程中分别都停留10s然后才退出,运行起来就会发现程序会阻塞十秒然后才会退出到主界面,说白了join()函数就是等待线程的结束才会继续执行,否则就一直阻塞在join()函数这块!!!

detach()函数

void fun()
{std::this_thread::sleep_for(std::chrono::seconds(100));cout << "AAAA" << endl;
}int main()
{thread th1(fun);th1.detach();cout << "BBBB" << endl;return 0;
}

上述代码我们可以看出应该是主线程运行之后,进入到子线程th1,然后在fun函数中阻塞100s,但是由于使用了detach()函数,使得主线程与子线程th1分离了,没关系了,但是随着主线程main的退出,子线程th1也将被退出!!!

join()和detach()函数之后,对线程再次进行joinable将会是false!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

【C++】多线程互斥锁、条件变量

我们了解互斥量和条件变量之前&#xff0c;我们先来看一下为什么要有互斥量和条件变量这两个东西&#xff0c;了解为什么有这两东西之后&#xff0c;理解起来后面的东西就简单很多了&#xff01;&#xff01;&#xff01; 先来看下面这段简单的代码&#xff1a; int g_num 0;…

【C++】二叉树的先序、中序、后序遍历序列

二叉树常用到的遍历有这三种 先序遍历&#xff1a;先遍历根节点&#xff0c;然后再分别遍历左节点和右节点。(根左右) 中序遍历&#xff1a;先遍历左节点&#xff0c;然后再遍历根节点&#xff0c;最后遍历右节点。(左根右) 后序遍历&#xff1a;先遍历左节点&#xff0c;然…

软件工程需求设计说明书

Java即时通聊天程序 设计需求说明书 专业班级&#xff1a; 计本班1202班 项目组成员&#xff1a; 杨宗坤 刘瑞 满亚洲 指导教师&#xff1a; 张利峰 开始日期&#xff1a; 完成日期&#xff1a; 编写目的&#xff1a; 本说明书是在充分理解系统需求分析…

【C++】菱形继承

我们先来看下菱形继承的基本视图以及基本的代码结构 下面来看下简单的代码以及数据结构&#xff1a; class Person { public:int a_p; };class Studen :public Person { public:int a_st; };class Stuff :public Person { public:int a_sf; };class st_sf :public Stuff, publ…

ie旋转滤镜Matrix

旋转一个元素算是一个比较常见的需求了吧&#xff0c;在支持CSS3的浏览器中可以使用transform很容易地实现&#xff0c;这里有介绍&#xff1a;http://www.css88.com/archives/2168&#xff0c;这里有演示http://www.css88.com/tool/css3Preview/Transform.html&#xff0c;就不…

【C++】四种类型的转换

C四种类型的转换 包括这四种&#xff1a;const_cast , static_cast , dynamic_cast , reinterpret_cast 先来说下C语言中的类型转换&#xff0c;非常的暴力&#xff0c;就是耍流氓&#xff1a; float a 12.23; int b (int)a; 下面我写的都是最基础的&#xff0c;简单的&am…

【C++】满二叉树、完全二叉树等概念解释

二叉树中的判断有以下几种&#xff1a; 是否完全二叉树、是否满二叉树、是否为BST树、是否为平衡二叉树、是否为对称二叉树、完美二叉树 满二叉树&#xff1a; 除最后一层无任何子节点外&#xff0c;每一层上的所有结点都有两个子结点的二叉树。 上述所示图除最外一层节点之外…

【C++】多线程(链式、循环队列)实现生产者消费者模式

生产者消费者模式&#xff1a; 生产者消费者问题&#xff08;英语&#xff1a;Producer-consumer problem&#xff09;&#xff0c;也称有限缓冲问题&#xff08;英语&#xff1a;Bounded-buffer problem&#xff09;&#xff0c;是一个多线程同步问题的经典案例。该问题描述了…