当前位置:   article > 正文

c++线程thread教程_c++ thread

c++ thread

c++线程thread

C++11/C++14 线程教程

thread类官网详解 thread类官网详解
参考链接

1.创建线程

直接初始话thread类对象进行创建线程,创建线程后调用join()方法,让主线程等待子线程完成工程。

#include <iostream>
#include <thread>

void thread_function()
{
    std::cout << "thread function\n";
}

int main()
{
    std::thread t(&thread_function);   // t starts running
    std::cout << "main thread\n";
    t.join();   // main thread waits for the thread t to finish
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.守护线程

我们可以调用detach()方法,将线程变为守护线程,完成线程和主线程的分离。一旦线程分离,我们不能强迫它再次加入主线程,再次调用join()方法会报错的。
一旦分离,线程应该永远以这种方式存在。调用join()函数之前可以使用函数joinable()检查线程是否可以加入主线程,加强程序健壮性。

// t2.cpp
int main()
{
    std::thread t(&thread_function);
    std::cout << "main thread\n";
    if( t.joinable( ) ) 
        // t.join();
    // t.join();
    t.detach();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3. 可调用对象

线程可以调用

  1. 函数指针
  2. 类对象
  3. lamda表达式

  1. 函数指针
    就像之前举例的样子

  2. 类对象

#include <iostream>
#include <thread>

class MyFunctor
{
public:
    void operator()() {
        std::cout << "functor\n";
    }
};

int main()
{
    MyFunctor fnctor;
    // 这样是不能运行的,
    // std::thread t(fnctor);

    // 必须按照这样进行初始话。
    // MyFunctor fnctor;  Note that we had to add () to enclose the MyFunctor(). 
    std::thread t((MyFunctor())); // it's related to the function declaration convention in C++.
    std::cout << "main thread\n";
    t.join();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  1. lamda表达式

int main()
{
    std::thread t([]()
    {
        std::cout << "thread function\n";
    }
    );
    std::cout << "main thread\n";
    t.join();     // main thread waits for t to finish
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

4. 传参

传参分为三种

  1. 值传递
  2. 引用传递
  3. 不复制,也不共享内存的传参方式move()
#include <iostream>
#include <thread>
#include <string>

void thread_function(std::string s)
{
    std::cout << "thread function ";
    std::cout << "message is = " << s << std::endl;
}

int main()
{
    std::string s = "Kathy Perry";
    // 1. 值传递
    std::thread t(&thread_function, s);
    // 2. 引用传递
    std::thread t(&thread_function, std::ref(s));
    // 3. 不复制,也不共享内存的传参方式`move()
    std::thread t(&thread_function, std::move(s));
    std::cout << "main thread message = " << s << std::endl;
    t.join();
    return 0;
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

5. 线程的移动和复制

// t5.cpp
#include <iostream>
#include <thread>

void thread_function()
{
    std::cout << "thread function\n";
}

int main()
{
    std::thread t(&thread_function);
    std::cout << "main thread\n";
    //  transfer the ownership of the thread by moving it:
    std::thread t2 = move(t);

    t2.join();

    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

6.线程id

获取线程的id: this_thread::get_id()
总共有多少个线程:std::thread::hardware_concurrency()

  • 程序
int main()
{
    std::string s = "Kathy Perry";
    std::thread t(&thread_function, std::move(s));
    std::cout << "main thread message = " << s << std::endl;

    std::cout << "main thread id = " << std::this_thread::get_id() << std::endl;
    std::cout << "child thread id = " << t.get_id() << std::endl;

    t.join();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 输出
thread function message is = Kathy Perry
main thread message =
main thread id = 1208
child thread id = 5224
  • 1
  • 2
  • 3
  • 4

7. 互斥mutex

互斥锁可能是 C++ 中使用最广泛的数据保护机制,但重要的是构造我们的代码以保护正确的数据并避免接口中固有的竞争条件。互斥锁也有自己的问题,表现为死锁和保护太多或太少的数据

标准 C++ 库提供了std::lock_guard类模板,它实现 了互斥锁的RAII习惯用法。它在构造时锁定提供的互斥锁并在销毁时解锁它,从而确保始终正确解锁锁定的互斥锁。


#include <iostream>
#include <thread>
#include <list>
#include <algorithm>
#include <mutex>

using namespace std;

// a global variable
std::list<int>myList;

// a global instance of std::mutex to protect global variable
std::mutex myMutex;

void addToList(int max, int interval)
{
	// the access to this function is mutually exclusive
	std::lock_guard<std::mutex> guard(myMutex);
	for (int i = 0; i < max; i++) {
		if( (i % interval) == 0) myList.push_back(i);
	}
}

void printList()
{
	// the access to this function is mutually exclusive
	std::lock_guard<std::mutex> guard(myMutex);
	for (auto itr = myList.begin(), end_itr = myList.end(); itr != end_itr; ++itr ) {
		cout << *itr << ",";
	}
}

int main()
{
	int max = 100;

	std::thread t1(addToList, max, 1);
	std::thread t2(addToList, max, 10);
	std::thread t3(printList);

	t1.join();
	t2.join();
	t3.join();

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/153478
推荐阅读
相关标签
  

闽ICP备14008679号