C++使用thread类进行多线程编程

C++11中引入了一个用于多线程操作的thread类,简单多线程示例:

#include <iostream>
#include <thread>
#include <Windows.h>

using namespace std;

void thread01()
{
    for (int i = 0; i < 5; i++)
    {
        cout << "Thread 01 is working !" << endl;
        Sleep(100);
    }
}
void thread02()
{
    for (int i = 0; i < 5; i++)
    {
        cout << "Thread 02 is working !" << endl;
        Sleep(200);
    }
}

int main()
{
    thread task01(thread01);
    thread task02(thread02);
    task01.join();
    task02.join();

    for (int i = 0; i < 5; i++)
    {
        cout << "Main thread is working !" << endl;
        Sleep(200);
    }
    system("pause");
}

输出:

两个子线程并行执行,join函数会阻塞主流程,所以子线程都执行完成之后才继续执行主线程。可以使用detach将子线程从主流程中分离,独立运行,不会阻塞主线程:

#include <iostream>
#include <thread>
#include <Windows.h>

using namespace std;

void thread01()
{
    for (int i = 0; i < 5; i++)
    {
        cout << "Thread 01 is working !" << endl;
        Sleep(100);
    }
}
void thread02()
{
    for (int i = 0; i < 5; i++)
    {
        cout << "Thread 02 is working !" << endl;
        Sleep(200);
    }
}

int main()
{
    thread task01(thread01);
    thread task02(thread02);
    task01.detach();
    task02.detach();

    for (int i = 0; i < 5; i++)
    {
        cout << "Main thread is working !" << endl;
        Sleep(200);
    }
    system("pause");
}

输出:

使用detach的主线程和两个子线程并行执行。

带参子线程

在绑定的时候也可以同时给带参数的线程传入参数:

#include <iostream>
#include <thread>
#include <Windows.h>

using namespace std;

//定义带参数子线程
void thread01(int num)
{
    for (int i = 0; i < num; i++)
    {
        cout << "Thread 01 is working !" << endl;
        Sleep(100);
    }
}
void thread02(int num)
{
    for (int i = 0; i < num; i++)
    {
        cout << "Thread 02 is working !" << endl;
        Sleep(200);
    }
}

int main()
{
    thread task01(thread01, 5);  //带参数子线程
    thread task02(thread02, 5);
    task01.detach();
    task02.detach();

    for (int i = 0; i < 5; i++)
    {
        cout << "Main thread is working !" << endl;
        Sleep(200);
    }
    system("pause");
}

输出跟上例输出一样:

多线程数据竞争

多个线程同时对同一变量进行操作的时候,如果不对变量做一些保护处理,有可能导致处理结果异常:

#include <iostream>
#include <thread>
#include <Windows.h>

using namespace std;

int totalNum = 100;

void thread01()
{
    while (totalNum > 0)
    {
        cout << totalNum << endl;
        totalNum--;
        Sleep(100);
    }
}
void thread02()
{
    while (totalNum > 0)
    {
        cout << totalNum << endl;
        totalNum--;
        Sleep(100);
    }
}

int main()
{
    thread task01(thread01);
    thread task02(thread02);
    task01.detach();
    task02.detach();
    system("pause");
}

输出结果(部分):

有两个问题,一是有很多变量被重复输出了,而有的变量没有被输出;二是正常情况下每个线程输出的数据后应该紧跟一个换行符,但这里大部分却是另一个线程的输出。

这是由于第一个线程对变量操作的过程中,第二个线程也对同一个变量进行各操作,导致第一个线程处理完后的输出有可能是线程二操作的结果。

针对这种数据竞争的情况,可以使用线程互斥对象mutex保持数据同步。

mutex类的使用需要包含头文件mutex:

#include <iostream>
#include <thread>
#include <Windows.h>
#include <mutex>

using namespace std;

mutex mu;  //线程互斥对象

int totalNum = 100;

void thread01()
{
    while (totalNum > 0)
    {
        mu.lock(); //同步数据锁
        cout << totalNum << endl;
        totalNum--;
        Sleep(100);
        mu.unlock();  //解除锁定
    }
}
void thread02()
{
    while (totalNum > 0)
    {
        mu.lock();
        cout << totalNum << endl;
        totalNum--;
        Sleep(100);
        mu.unlock();
    }
}

int main()
{
    thread task01(thread01);
    thread task02(thread02);
    task01.detach();
    task02.detach();
    system("pause");
}

多线程中加入mutex互斥对象之后输出正常:

后记:

C++11之前,Windows系统为我们提供了相关API,我们可以使用他们来进行多线程编程

C++11 thead 多线程类

原文地址:https://www.cnblogs.com/ZY-Dream/p/10037428.html

时间: 2024-12-11 00:17:15

C++使用thread类进行多线程编程的相关文章

多线程介绍与threading模块应用以及使用Thread类创建多线程

1.多线程: 多线程是为了同步完成多项任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率.线程是在同一时间需要完成多项任务的时候实现的. 最简单的比喻多线程就像火车的每一节车厢,而进程则是火车.车厢离开火车是无法跑动的,同理火车也不可能只有一节车厢.多线程的出现就是为了提高效率.同时它的出现也带来了一些问题. 线程与进程的关系: 进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行.一个程序运行至少一个进程,一个进程里

thread模块—Python多线程编程

Thread 模块 *注:在实际使用过程中不建议使用 thread 进行多线程编程,本文档只为学习(或熟悉)多线程使用. Thread 模块除了派生线程外,还提供了基本的同步数据结构,称为锁对象(lock object,也叫原语锁.互斥锁.互斥和二进制信号量). 常用线程函数以及 LockType 锁对象的方法: 函数/方法 描述 thread 模块的函数   start_new_thread(function, args, kwargs=None) 派生一个新的线程,使用给定的 args 和可

通过继承Thread类实现多线程

(1)继承Thread类(2)重写run(方法(3)通过start0方法启动线程 一定的缺点: Java中的类是单继承的,一旦继承了Thread类,就不允许再去继承其它的类 线程和主方法之间的执行顺序不一定,取决于CPU调度的先后 原文地址:https://www.cnblogs.com/LuJunlong/p/12090936.html

java多线程同步以及线程间通信详解&amp;消费者生产者模式&amp;死锁&amp;Thread.join()(多线程编程之二)

本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: [java] view plain copy print? package com.zejian.test; /** * @author zejian * @time 2016年3月12日 下午2:55:42 * @decrition 模拟卖票线程 */ public class Ticket implements Runnable { //当前拥有的票数 private 

多线程编程之线程基础

前言 此内容是阅读了书籍<JAVA多线程编程核心技术>后作为学习总结的文章,同时也梳理一下内容.建议大家有兴趣都可以阅读一下这本书,对于想了解更多的同学来说是一个很好的教材,同时建议大家多去思考和动手编写代码,融会贯通之后再去看一遍,会有更多的体会.就比如<JVM底层实现最佳实战>的书籍一样,我读了已经不下五遍了,但每次读都能有新的收获一样.希望对大家有帮助. 该篇文章是用于了解多线程的一些基本概念.JDK支持多线程编程的类和方法,接口等. 1.1 进程与线程概念 什么是进程: 进

多线程编程--创建线程之Thread VS Runnable

前面写过一篇基础的创建多线程的博文: 那么本篇博文主要来对比一下这两种创建线程的区别. 继承Thread类: 还拿上篇博客的例子来说: 四个线程各自卖各自的票,说明四个线程之间没有共享,是独立的线程.每个线程平等,没有优先级关系.这三个线程不是一次交替执行,而是三个线程同时被执行的情况下,有的线程被分配时间片的机会多,票被提前卖完,有的线程被分配的时间片的机会少,票迟一些卖完. 故,利用扩展Thread类创建的多个线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰. 分

探Java多线程Thread类和Runnable接口之间的联系

首先复习一下Java多线程实现机制,Java实现多线程方法有如下这么几种: 1.继承了(extends)Thread类 2.实现了(implements)Runnable接口 也就是说  有如下两种情况 情况1: 继承Thread类.重写其方法run() .    然后new之.调用Start()方法 1 public class TestThread 2 { 3 private int i; 4 public static void main(String[] args) 5 { 6 // T

Java通过继承thread类与实现Runnable接口实现多线程的区别

Java中线程的创建有两种方式: 1.  通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2.  通过实现Runnable接口,实例化Thread类 一.通过继承Thread类实现多线程 class MyThread extends Thread{ String name = null; int ticket = 0; public MyThread(String name){ this.name = name; } public synchronized v

Java多线程实现1,继承Thread类

Java可以通过继承Thread类实现多线程,具体步骤如下: 定义一个新的类继承自Thread类. 在新的类中实现run()方法,此方法即为新线程的运行程序代码. 创建一个新的类的对象,并调用对象的start()方法. Thread存放在java.lang类库里,但并不需加载java.lang类库,因为它会自动加载.此外,run()方法是定义在Thread类里的一个方法,把线程的程序代码编写在run()方法内,事实上所做的就是覆盖的操作.下面是用此方式实现多线程的一个例子: public cla