zoukankan      html  css  js  c++  java
  • 线程的使用

    // ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include <iostream>
    #include"stdafx.h"
    #include<vector>
    #include<map>
    #include<string>
    #include<thread>
    
    
    
    
    using namespace std;
    //线程类型可以是函数,仿函数,lamda表达式
    
    class TA
    {
    public:
        int m_i;
        TA(int i) :m_i(i) 
        {
            cout << "TA构造函数被执行 " << endl;
        }
        TA(const TA &ta):m_i(ta.m_i)
        {
            cout << "TA拷贝构造函数被执行 " << endl;
        }
        void operator()()//不能带参数
        {
            cout << "m_i1的值为:" << m_i  << endl;
            cout << "m_i2的值为:" << m_i << endl;
            cout << "m_i3的值为:" << m_i << endl;
            cout << "m_i4的值为:" << m_i << endl;
            cout << "m_i5的值为:" << m_i << endl;
            cout << "m_i6的值为:" << m_i << endl;
            //....
            //...
            //...
            cout << "我的线程执行完毕" << endl;
    
        }
        ~TA()
        {
            cout << "析构函数调用" << endl;
        }
    };
    //自己创建的线程也要从函数开始运行
    void myPrint()
    {
        cout << "我的线程开始执行" << endl;
        //....
        //...
        //...
        cout << "我的线程执行完毕" << endl;
    
    }
    
    int main()
    {
    //1.范例演示进程运行的开始和结束
        //可执行程序运行起来生成一个进程,该进程的主线程开始自动运行
    
        //cout << "I love china" << endl;//实际上是主线程在执行,主线程从main函数返回则整个进程执行完毕
        //主线程从main开始实行,自己的线程也需要从一个函数开始执行(初始函数),一旦这个函数运行完毕 就代表线程运行结束。
        //整个进程是否执行完毕标志是主线程是否执行完,如果主线程执行完毕代表整个进程执行完毕
        //此时,一般情况如果其他子线程还没有执行完毕,那么这些子线程也会被操作系统强行终止。
        //所以一般情况下,我们得出一个结论,如果大家想保持子线程运行状态的话,那么大家要让主线程一直运行,到子线程运行完毕
        //【这条规律有意外 后续解释】
        
    
        //a)包含thread头文件
        //b)写初始函数
        //c) main 中开始写代码
        //一个书写良好的程序,应该是主线程等待子线程执行完毕后,自己才能退出
        //明确一点 : 有两个线程在跑,相当于两条线同时走。同时干两个事 即使 一条线被堵住,另外一条线还是可以同行,这就是多线程
    
    
    
        //(1.1)thread是标准库里的一个类
        //(1.2)join();加入/汇合,阻塞主线程,让主线程等待子线程执行完毕,然后子线程和主线程汇合 
        //(1.3)detach():传统多线程程序要等待子线程执行完毕,然后再自己退出
        //detach :分离 也就是子线程不和主线程汇合,主线程和子线程各走各的,主线程不等子线程,可以先执行结束
        //为什么引入detach():我们创建了很多子线程,让主线程逐个等待子线程结束,不好,引入detach
        //一旦detach()之后,与这个主线程相关联的thread对象就会失去与这个主线程的关联,此时这个子线程就会驻留在后台运行了(主线程与改子线程失去联系)
        //这个子线程就相当于被c++运行时库接管,当这个子线程执行完成后,由运行时库负责清理该线程相关的资源(守护线程)。
    
    
    
        //thread mytobj(myPrint);//myPrint可调用对象。 (1)创建了线程,线程入口是myPrint(2)myPrint开始执行
        //mytobj.join();//主线程阻塞到这里,等待myPrint()执行完,当子线程执行完毕,主线程继续往下走
    
        //if (mytobj.joinable())
        //{
        //    cout << "joinabel is ture" << endl;
        //}
        //else
        //{
        //    cout << "joinabel is false" << endl;
        //}
        //mytobj.join();
        //mytobj.detach();
        //一旦使用了detach 就不能加入join 否则系统会报异常
        //阻塞主线程并等待myPrint()子线程执行完
    
    
        //(2.1)用类,以及一个问题范例
        //int myi = 6;
        //TA ta(myi);
        //thread myobj3(ta);//ta可调用对象 主线程执行完毕后 ta被析构,但是可以用
        //原因是:虽然对象不在了,但是对象实际上是被复制到了线程中去,执行完主线程后,ta会被销毁,但是所复制的ta对象依旧存在
        //所以只要对象中没有引用,没有指针都没有问题。
    
        //myobj3.join();//等待子线程执行结束
        //myobj3.detach();//主线程执行完 myi内存被回收,myi中没有内容,打印产生不可预料的后果 如果不是引用是一个值就没有关系
    
    
    
        //(2.2)用lamba表达式
        auto mylamthread = [] {
            cout << "我的线程3开始执行了" << endl;
            //.....
            //.....
            //....
            cout << "我的线程3执行结束了" << endl;
        };
        thread myobj4(mylamthread);
        myobj4.join();
    
        cout << "I love China" << endl;
    
        return 0;
    
    
    }
  • 相关阅读:
    PAT 1097. Deduplication on a Linked List (链表)
    PAT 1096. Consecutive Factors
    PAT 1095. Cars on Campus
    PAT 1094. The Largest Generation (层级遍历)
    PAT 1093. Count PAT's
    PAT 1092. To Buy or Not to Buy
    PAT 1091. Acute Stroke (bfs)
    CSS:word-wrap/overflow/transition
    node-webkit中的requirejs报错问题:path must be a string error in Require.js
    script加载之defer和async
  • 原文地址:https://www.cnblogs.com/ymj11/p/13855515.html
Copyright © 2011-2022 走看看