Linux多线程_神厨小福贵!的博客-CSDN博客进程和线程的区别有哪些呢?进程是资源分配的最小单位,线程是CPU调度的最小单位进程有自己的独立地址空间,线程共享进程中的地址空间进程的创建消耗资源大,线程的创建相对较小进程的切换开销大,线程的切换开销相对较小进程:程序执行的过程叫进程。线程:进程内部的一条执行序列或执行路径,一个进程可以包含多条线程(多线程)!每个进程最少有一个线程,例如下面代码:#include
进程是资源分配的最小单位,线程是CPU调度的最小单位
进程有自己的独立地址空间,线程共享进程中的地址空间
进程的创建消耗资源大,线程的创建相对较小
进程的切换开销大,线程的切换开销相对较小
进程:程序执行的过程叫进程。
线程:进程内部的一条执行序列或执行路径,一个进程可以包含多条线程(多线程)!
每个进程最少有一个线程,例如下面代码:
#includeusing namespace std; int main() { return 0; }
虽然只有一个主函数main,主函数的线程又叫主线程,其他的线程都叫它的子线程。
上面看完之后大致明白了线程的进程的区别,下面我们来看一下常用到的函数有哪些:上图来自于C++帮助文档:
std::thread - cppreference.comhttps://zh.cppreference.com/w/cpp/thread/thread
先来看第一个构造函数:打开它的构造函数,我们可以看到:
上图我们可以看到我们在下面这行代码后有个delete,也就是拷贝构造函数被删除了,不可以通过拷贝构造来创建线程!
thread( const thread& ) = delete;
我们只能通过缺省构造,移动构造,函数构建和类对象来构建对象!!!
缺省构建:#includeusing 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!!!


