进程和线程这部分呢我之前在我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也将被退出!!!