C++多线程基础

C++多线程

线程的概念

线程(thread)是计算机科学中的一个重要概念,它是进程(process)中的一个执行单元。简而言之,一个进程可以包含多个线程,每个线程可以独立执行不同的任务。

与进程相比,线程更轻量级,因为它们共享相同的内存空间和系统资源。这意味着在同一个进程中的线程可以更快地进行通信和数据共享,相比于不同进程之间的通信开销更小。

线程可以同时执行多个任务,使得程序能够更高效地利用多核处理器的并行能力。例如,在一个网络服务器应用程序中,可以使用多个线程来处理并发的客户端请求,从而提高服务器的响应速度。

线程之间可以通过共享内存进行通信,也可以使用同步机制(如互斥锁、条件变量等)来实现线程间的协调与同步。然而,由于多个线程共享同一份数据,因此在编写多线程程序时需要特别注意线程安全问题,以避免数据竞争和其他潜在的并发问题。

总结起来,线程是进程中的执行单元,它们能够同时执行多个任务,提高程序的性能和响应能力。

Thread

C++11中加入了头文件,此头文件主要声明了std::thread线程类。

线程涉及到操作系统的内容,如果学习了操作系统之后再来学习这部分的内容会更好一点。

创建进程

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

void Func1(){
	cout << "Hello world" << endl;
}

int main(){
    //在这里创建一个进程T1
    thread T1(Func1);
    return 0;
}

如果复制这样子的代码到VS2022中运行,会出现这样子的情况
在这里插入图片描述

原因:

这个线程是在main的进程里面的一个分支,到了main函数的结尾的,函数return返回了结束了,但是Func1这个进程却没有结束,因此会出现错误。

在多线程中,怎么理清楚每个线程之间的执行顺序是难点

在thread中有许多的成员函数:

  1. **joinable:**检查线程是否可被join。检查thread对象是否标识一个活动(active)的可行性线程。缺省构造的thread对象、已经完成join的thread对象、已经detach的thread对象都不是joinable。

  2. **join:**调用该函数会阻塞当前线程。阻塞调用者(caller)所在的线程直至被join的std::thread对象标识的线程执行结束

在调用join()成员函数的时候,他会先去判断joinable

在这里插入图片描述

如果在主进程中加入join函数,那么就当于是说,我先将当前的T1执行结束之后,在去执行主进程

保证了进程的执行顺序

#include <thread>
#include<iostream>
using namespace std;
void Func1() {
    cout << "Hello world" << endl;
}
int main() {
    //在这里创建一个进程T1
    thread T1(Func1);
    T1.join();
    return 0;
}

在这里我重新创建了一个新的函数Func2

如果thread T2(Func2,"Hello Func2");第一个相当于函数入口,第二个参数是传入函数入口的参数

如果不传入参数的话,程序也会报错

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

void Func1() {
    cout << "Hello world" << endl;
}

void Func2(const char* str) {
    cout << "Func2:" << str << endl;
}

int main() {
    //在这里创建一个进程T1
    thread T1(Func1);
    thread T2(Func2,"Hello Func2");
    T1.join();
    T2.join();
    return 0;
}

在这里我们又发现了一个问题

在这里插入图片描述

在代码中,我明明是有换行的啊,为什么在这里我的换行没有了呢?

这里理解的话:理解成,两个进程都抢着要执行,一个进程还没有完完全全的执行完毕,另外一个进程就开始执行了。因为多线程的不确定性,代码的执行顺序不一定是按照我们以为的那样子。

如果要解决的话,就是用加锁的操作,把两个进程之间完全的分开

mutex锁(互斥锁)

如果一个进程或者线程你保证没有别的与他竞争,那么你可以考虑不用加锁

对于子进程可能抢占共享资源的,我们都需要加锁的操作,防止对共享资源的抢占。

cout和cin这样的输入和输出端也是属于共享资源

在进入进程的时候lock,离开的时候unlock(释放)

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

mutex Func_mutex;//创建一个锁对象
void Func1() {
    Func_mutex.lock();
    cout << "Hello world" << endl;
    Func_mutex.unlock();
}

void Func2(const char* str) {
    Func_mutex.lock();
    cout << "Func2:" << str << endl;
    Func_mutex.unlock();
}

int main() {
    //在这里创建一个进程T1
    thread T1(Func1);
    thread T2(Func2,"Hello Func2");
    T1.join();
    T2.join();
    return 0;
}

可以看到输出的结果果然变了

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值