线程demo_C++
Demo of Thread
苦于每次写就忘的经历,我又写了一个简单的没有质量的Demo,因为太闲了,写完这篇就开始刷题吧
三个文件,People.h
,People.cpp
,main.cpp
。三个文件,两样东西,一个是People的类,一个是main函数调用线程。
People头文件及cpp文件
// profile: People头文件 #pragma once #include <iostream> #include <string> #include <vector> #include <algorithm> #include <Windows.h> #include <stdlib.h> using namespace std; static int constructTimes = 0; static int copyTimes = 0; class People { public: People(string str); People(const People &mt); ~People(); void setName(string str); void startWork(int s); void endWork(int e); void calcWorkTime(); private: string m_name; int m_start; int m_end; };
// profile: people.cpp文件 #include "People.h" People::People(string str) :m_name(str) { constructTimes++; cout << "构造次数:" << constructTimes << endl; } People::People(const People &mt) : m_name(mt.m_name) { copyTimes++; cout << "构造次数:" << copyTimes << endl; } People::~People() { cout << this->m_name << " 调用了析构函数" << endl; } void People::setName(string str) { cout << "更换岗位开始,需等待片刻" << endl; int i; for (i = 0; i < 3; i++) { Sleep(1000); cout << "更换岗位ing……" << endl; } this->m_name = str; cout << str << " 设置工作成功,耗时"<< i <<"S" << endl; } void People::startWork(int s) { cout << m_name << " 开始工作,开始时间:" << s << endl; m_start = s; } void People::endWork(int e) { cout << m_name << " 结束工作,开始时间:" << e << endl; m_end = e; } void People::calcWorkTime() { cout << m_name << " 的工作时长为:"; cout << m_end - m_start << endl; }
主函数文件
std::ref()与std::cref()的区别
使用std::ref()不会调用拷贝构造函数,因为std::ref是引用传递,函数内部的修改影响外面,这里传的必须是指针
使用 std::cref() 相当于 std::const ref(),const 引用传递,函数内部不能修改
#include <iostream> #include <thread> #include "People.h" class People; using namespace std; int main(int argc, const char * argv[]) { People p1("aaa"); cout << "线程:" << std::this_thread::get_id() << "开始" << endl; int startTime = 1,endTime; People *p1ptr = &p1; // 这里如果使用的是p1,则允许setName函数内部修改值,但不会对外部影响 // 使用std::ref()不会调用拷贝构造函数,因为std::ref是引用传递,函数内部的修改影响外面,这里传的必须是指针 // 使用 std::cref() 相当于 std::const ref(),const 引用传递,函数内部不能修改 std::thread w1(&People::setName, std::ref(p1ptr), "bbb"); std::thread w2(std::move(w1)); // 线程为w2开始运行setName,w1不再作为一个线程对象 bool w1Joinable = w1.joinable(); cout << "w1的joinable:" << w1Joinable << endl; w2.detach(); // detach 是脱离主线程,单独在一个线程中进行,屏幕输出就会乱序 // w1.join() 是加入到线程 cout << "-----------" << endl; p1.startWork(1); for (auto i = 0; i < 5; i++) { Sleep(1000); cout << "工作ing……" << endl; endTime = i; } p1.endWork(endTime); p1.calcWorkTime(); system("pause"); return 0; }
输出:
构造次数:1
线程:17668开始
更换岗位开始,需等待片刻w1的joinable: 0
-----------
aaa 开始工作,开始时间:1
工作ing……
更换岗位ing……
更换岗位ing……
工作ing……
更换岗位ing……
bbb 设置工作成功,耗时3S
工作ing……
工作ing……
工作ing……
bbb 结束工作,开始时间:4
bbb 的工作时长为:3
线程:17668开始
更换岗位开始,需等待片刻w1的joinable: 0
-----------
aaa 开始工作,开始时间:1
工作ing……
更换岗位ing……
更换岗位ing……
工作ing……
更换岗位ing……
bbb 设置工作成功,耗时3S
工作ing……
工作ing……
工作ing……
bbb 结束工作,开始时间:4
bbb 的工作时长为:3
因为是detach()
的方式,因此更换岗位与工作是异步进行的。也就是这是两个单独的线程在进行。
本文来自博客园,作者:StimuMing,转载请注明原文链接:https://www.cnblogs.com/fole-del/p/14545374.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步