c++11 多线程简介

c++11 增加了的多线程的模块

头文件:#include <thread>

常用的几个函数简介

1. join()

该函数主要是运行子线程(并行运行),阻塞主线程,等待所有子线程完成时,继续执行主线程;

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

using namespace std;
void thread01(void)
{
    for (int i = 0; i < 5; i++)
    {
        cout << "Thread 001 is working ..." << endl;
        Sleep(100);
    }
}

void thread02(void)
{
    for (int i = 0; i < 5; i++)
    {
        cout << "thread 002 is working ..." << endl;
    }
}
int main(void)
{
    thread task01(thread01);
    thread task02(thread02);
    task01.join();
    task02.join();
    
    for (int i = 0; i < 10; i++)
    {
        cout << "Main thread is working ..." << endl;
    }
    
    return 0;
 } 

输出结果:

Thread 001 is working ...thread 002 is working ...

thread 002 is working ...
thread 002 is working ...
thread 002 is working ...
thread 002 is working ...
Thread 001 is working ...
Thread 001 is working ...
Thread 001 is working ...
Thread 001 is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...

--------------------------------
Process exited after 0.8741 seconds with return value 0
请按任意键继续. . .

2. detach()

该函数将子线程与主线程分离,子线程不阻塞主线程,各自独立且并行运行,但是在主线程结束时,并将导致子线程结束。

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

using namespace std;

void thread01(void)
{
    for (int i = 0; i < 5; i++)
    {
        cout << "thread 001 is working ..." << endl;
        Sleep(100); 
    }
 } 
 
 void thread02(void)
 {
     for (int i = 0; i < 5; i++)
     {
         cout << "thread 002 is working ..." << endl;
         Sleep(100);
     }
 }
 
 
 int main(void)
 {
     thread task01(thread01);
     thread task02(thread02);
     task01.detach();
     task02.detach();
     
     for (int i = 0; i < 10; i++)
     {
         cout << "Main thread is working ..." << endl;
         Sleep(10); 
     }
     return 0;
 }

输出结果:

Main thread is working ...thread 001 is working ...

thread 002 is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
Main thread is working ...
thread 001 is working ...
Main thread is working ...
Main thread is working ...
thread 002 is working ...
Main thread is working ...
Main thread is working ...

--------------------------------
Process exited after 0.408 seconds with return value 0
请按任意键继续. . .

3. 带参数的子线程

在创建子线程时,可以传递带参数的子线程,其中创建线程的方法如下:

public member function 
std::thread::thread

default (1)   
thread() noexcept;

initialization (2)    
template <class Fn, class... Args>
explicit thread (Fn&& fn, Args&&... args);

copy [deleted] (3)    
thread (const thread&) = delete;

move (4)    
thread (thread&& x) noexcept;

Constructs a thread object:
(1) default constructor
Construct a thread object that does not represent any thread of execution.
(2) initialization constructor
Construct a thread object that represents a new joinable thread of execution.
The new thread of execution calls fn passing args as arguments (using decay copies of its lvalue or rvalue references).
The completion of this construction synchronizes with the beginning of the invocation of this copy of fn.
(3) copy constructor
Deleted constructor form (thread objects cannot be copied).
(4) move constructor
Construct a thread object that acquires the thread of execution represented by x (if any). This operation does not affect the execution of the moved thread in any way, it simply transfers its handler.
The x object no longer represents any thread of execution.

thread objects that are joinable shall either be joined or detached before they are destroyed.

Parameters
fn
A pointer to function, pointer to member, or any kind of move-constructible function object (i.e., an object whose class defines operator(), including closures and function objects).
The return value (if any) is ignored.
args...
Arguments passed to the call to fn (if any). Their types shall be move-constructible.
If fn is a member pointer, the first argument shall be an object for which that member is defined (or a reference, or a pointer to it).
x
thread object whose state is moved to the constructed object.
Fn and Args... are template parameters: if implicitly deduced, these are the proper lvalue or rvalue reference type to bind the arguments to. Note though, that on the call to fn in the new thread, decay copies of fn and args... are always used (see std::ref for a wrapper class that makes references copyable).        
#include <iostream>
#include <thread>
#include <Windows.h>
using namespace std;
void thread01(int num)
{
    for (int i = 0; i < num; i++)
    {
        cout << "thread 001 is working ...." << endl;
        Sleep(200);
    }
}

void thread02(int num)
{
    for (int i = 0; i < num; i++)
    {
        cout << "thread 002 is working ... "  << endl;
        Sleep(200);
    }
}


int main(void)
{
    thread task01(thread01, 5);
    thread task02(thread02, 5);
    task01.join();
    task02.join();
    
    for (int i = 0; i < 3; i++)
    {
        cout << "Main thread is working ..." << endl;
        Sleep(100);
    }
    return 0;
}

输出结果:

thread 001 is working ....thread 002 is working ...

thread 001 is working ....
thread 002 is working ...
thread 002 is working ...
thread 001 is working ....
thread 002 is working ...
thread 001 is working ....
thread 002 is working ...
thread 001 is working ....
Main thread is working ...
Main thread is working ...
Main thread is working ...

--------------------------------
Process exited after 1.545 seconds with return value 0
请按任意键继续. . .

4. 多线程数据竞争

当多个线程同时对一个变量进行操作时,如果不对变量进行一些保护处理,有可能会获得一些异常的结果。针对这种情况,可以采用线程互斥锁,使互斥对象保持同步。

使用头文件:<mutex>

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

using namespace std;
int total = 100;
mutex mu; //线程互斥对象

void thread01(void)
{
    while (total > 0)
    {
        mu.lock();  //同步数据锁
        cout << total << endl;
        total--;
        Sleep(100);
        mu.unlock(); //解除锁定  
    }
 } 
 
 void thread02(void)
 {
     while (total > 0)
     {
         mu.lock();  //同步数据锁
         cout << total << endl;
         total--;
         Sleep(100);
         mu.unlock(); //解除锁定  
     }
 }
 
 
 int main(void)
 {
     thread task01(thread01);
     thread task02(thread02);
     
     task01.detach();
     task02.detach();
    system("pause");
    return 0; 
 }

5. joinable()

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

 

posted on 2018-04-30 21:20  萧飞IDO  阅读(255)  评论(0编辑  收藏  举报

导航