并发、线程的基本概念&线程启动结束

并发、进程、可执行程序、进程、线程的基本概念

1.并发 
并发当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。每次切换需要额外的开销(保存运行状态、还原现场)占用程序运行时间。线程的数量过多效率反而下降。
2.并行
当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行。
3.可执行程序
一个文件,windows下以.com或.exe为后缀,liunx,ls -la,rwxrwxrwx(x执行权限)
4.进程
计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。(可执行程序运行起来)
5.线程
又叫轻量进程,是程序执行流的最小单元。每一个进程有一个主线程,可以有多个线程。一个进程内的线程共享内存(全局变量、指针、引用可在线程间传递,开销小于多进程,但是会造成数据一致性的问题)。

线程启动结束

主线程从main()函数开始,自己创建的线程也需要从一个函数开始执行,这个函数执行完成,则线程消亡。
如果主线程结束,进程结束,一般情况下该进程的所有线程结束。
thread:标准库里的一个类

join() (汇合)

join:阻塞主线,让主线程等待子线程执行完毕
用函数

#include<iostream>
#include<thread>
using namespace std;
void print()
{
    cout<<"子线程开始"<<endl;
    cout<<"子线程结束"<<endl;
}
int main()
{
    thread myThread(print);  //创建线程(入口为print())
    myThread.join();         //阻塞主线程 等待子线程执行完成
    cout<<"主线程结束"<<endl;
    return 0;
}

用类对象

#include<iostream>
#include<thread>
using namespace std;
class TA
{
public:
    void operator()()  //重载(),不能带参数
    {
        cout<<"子线程开始"<<endl;
        cout<<"子线程结束"<<endl;
    }

};

int main()
{
    TA ta;
    thread myThread(ta);     //传入可调用对象
    myThread.join();         //阻塞主线程 等待子线程执行完成
    cout<<"主线程结束"<<endl;
    return 0;
}

用lambda表达式

#include<iostream>
#include<thread>
using namespace std;

int main()
{
    auto my = []{
        cout<<"子线程"<<endl;
    };
    thread myThread(my);     //传入可调用对象
    myThread.join();
    return 0;
}

如果去掉myThread.join();可能会出现主线程执行完后子线程未执行完成。

detach() (分离)

detach:主线程和子线程分离,主线程可以先执行完成,不用和子线程汇合。
detach后主线程关联和thread对象会与主线程失去关联,子线程会到后台运行。

以下程序有一个坑点!!!

在用detach()时,当主线程执行完成后,类中值引用的主线程局部对象val将会被回收,但是子线程依然要打印val的值,此时程序时错误的!(引用,指针局部对象)
创建子线程中的局部的类对象是被复制到线程中去的,所以没有问题。

#include<iostream>
#include<thread>
using namespace std;
class TA
{
public:
    int &val;
    TA(int &val):val(val){}
    void operator()()  //重载(),不能带参数
    {
        cout<<val<<endl;
    }
};

int main()
{
    int val=100;
    TA ta(val);
    thread myThread(ta);     //传入可调用对象
    myThread.detach();
    return 0;
}

joinable()

判断是否能join()或detach()

posted @ 2019-02-14 02:53  xcantaloupe  阅读(343)  评论(0编辑  收藏  举报