C++多线程编程:包括多线程打印ABC、线程池实现等等

发布时间 2023-09-08 19:27:20作者: timeMachine331
#include<iostream>
#include<thread>
#include<mutex>
#include<condition_variable>

std::condition_variable cond;
std::mutex print_mutex;
int flag = 0;

void print_thread(int num)
{
    for (int i = 0; i < 10; i++)  // 循环
    {
        std::unique_lock<std::mutex> lk(print_mutex);
        cond.wait(lk, [&]() {return num == flag; });
        std::cout << char('A' + num);  // 打印ABC,
        flag = (flag + 1) % 3;
        cond.notify_all();
    }
}

int main()
{
    std::thread t1(print_thread, 1);
    std::thread t2(print_thread, 2);
    print_thread(0);
    t1.join();
    t2.join();
}

这段代码在跨平台时会报错,因为安装的MinGW没有选用支持POSIX的版本。

这是因为MinGW没有thread类,对于跨平台的线程实现,GCC标准库似乎依赖于gthreads/pthreads库。如果这个库不可用,就像MinGW一样,std::thread、std::mutex、std::condition_variable类不会被定义。然而,各种可用的helper类仍然定义在系统头文件中。因此,这个实现没有重新定义它们,而是包含了这些头文件。
解决方案:换成pthread或者        https://github.com/meganz/mingw-std-threads

https://github.com/meganz/mingw-std-threads

在github上能够找到MinGW-std-threads,这个文件中包含MinGW.mutx.h, MinGW .thread.h文件并把它们放到全局MinGW目录下就可以修复了这个问题。

 将这几个文件放到MinGW的安装路径:mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\c++

我的电脑上是在F:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include\C++

观察这个代码和上面的代码,修改的地方时需要将头文件#include<thread> 改为 # include<mingw.thread.h>

#include<iostream>
#include <mingw.thread.h>
#include <mingw.mutex.h>
#include <mingw.condition_variable.h>

std::condition_variable cond;
std::mutex print_mutex;

int flag = 0;

void print_thread(int num)
{
    for (int i = 0; i < 10; i++)  // 循环
    {
        std::unique_lock<std::mutex> lk(print_mutex);
     //捕获列表只用于非静态局部变量,Lambda可以直接使用静态局部变量和在函数之外声明的名字(全局变量)。 cond.wait(lk, [
&]() {return num == flag; }); std::cout << char('A' + num); // 打印ABC, flag = (flag + 1) % 3; cond.notify_all(); } } int main() { std::mutex print_mutex; std::thread t1(print_thread, 1); std::thread t2(print_thread, 2); print_thread(0); t1.join(); t2.join(); }

其他全正常的。

 使用switch case的写法,在ABC之间切换,需要使用flag作为基准唤醒某一个。

可是这样的循环打印有什么意义呢?任务不是派发的。

#include<iostream>
#include <mingw.thread.h>
#include <mingw.mutex.h>
#include <mingw.condition_variable.h>

std::condition_variable cond;
std::mutex print_mutex;

int flag = 0;

void print_thread(int num)
{
    for (int i = 0; i < 10; i++)  // 循环
    {    
        //unique_lock 在超出作用域后会析构,从而自动解锁
        std::unique_lock<std::mutex> lk(print_mutex);
        //condition_variable::wait     true立即返回 false阻塞线程,等待期间会释放这个锁
        //捕获列表只用于非静态局部变量,Lambda可以直接使用静态局部变量和在函数之外声明的名字(全局变量)。
        cond.wait(lk, [&num]() {return num == flag; });
        switch(num){
            case 0: flag = 1; std::cout << "A" << std::endl; break;
            case 1: flag = 2; std::cout << "B" << std::endl; break;
            case 2: flag = 0; std::cout << "C" << std::endl; break;
        }

        //'A'+num 可是num只会为1或者2,为1时打印B 为2时打印C,0是在主线程里打印,那是不是也可以开三个线程。
        //std::cout << char('A' + num);  // 打印ABC,
        //flag = (flag + 1) % 3;
        cond.notify_all();
    }
}

int main()
{   
    std::thread t1(print_thread, 1);
    std::thread t2(print_thread, 2);
    std::thread t0(print_thread, 0);
    //print_thread(0);
    t1.join();
    t2.join();
    t0.join();
    //Sleep(10);
}