栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c++11新特性之多线程总结

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c++11新特性之多线程总结

c++11新特性之多线程总结

文章目录
  • c++11新特性之多线程总结
  • 一、线程初始化方式
  • 二、总结
    • 1.detach()是将子线程与主线程分离,成为孤儿线程
    • 2.孤儿线程通信方式:
    • 3.主线程传递给子线程的对象要用ref(),防止拷贝(特别传入孤儿线程)
    • 4.线程之间共享的数据要加锁,而且是同一把锁
    • 5.如果条件变量用于孤儿线程,主线程不能提前结束,要等待孤儿线程的条件变量通信完成
    • 6.多个线程共享的自定义类用智能指针,而且要使用ref()防止拷贝,
    • 7.线程处于阻塞状态时,有一定概率出现虚假唤醒,要使用while来避免
    • 8.信号丢失问题通常出现在线程执行顺序错误
    • 9.std::cout也是要争抢的资源
    • 10.在共享类里面给共享数据加锁,并且要写数据时要加容错处理
    • 11.cv.wait(u_lock,lambda),等待结束的条件是:u_lock收到notify并且lambda返回值为true,一定要两个同时满足!!!!!!!!!!
  • 三、示例:巨多生产者和消费者同时并发
  • 四、线程池


一、线程初始化方式
//初始化
	std::thread thread_1(thread1);
	if (thread_1.joinable()) thread_1.join();
	std::thread thread_2(thread2, 2);
	if (thread_2.joinable()) thread_2.join();
	std::thread(thread2, 3).detach();
	auto lambda = [](int a) {

		std::cout << "lambda : " << a << std::endl;
	};
	std::thread thread_3(thread3, 3);
	std::this_thread::sleep_for(std::chrono::seconds(5));//主线程延时

	std::thread thread_4(thread4, 4);
	std::thread thread_5(lambda, 5);
	std::cout << "当前 cpu 个数 " << std::thread::hardware_concurrency() << std::endl;

	if (thread_3.joinable())
		thread_3.join();

	if (thread_4.joinable())
		thread_4.join();

	if (thread_5.joinable())
		thread_5.join();
二、总结 1.detach()是将子线程与主线程分离,成为孤儿线程 2.孤儿线程通信方式:
#include 

std::mutex cv_mutex;

void produceA(std::queue& q) {
	std::unique_lock lock;
	for(auto i = 0; i < 10; ++i){
		q.push('A');
	}
	
}
void produceB(std::queue& q) {

	std::unique_lock lock;
	for (auto i = 0; i < 10; ++i) {
		q.push('B');
	}
}

int main(){
	std::queue q;
	std::thread produceA_thread(produceA, ref(q));
	produceA_thread.detach();
	std::thread produceB_thread(produceB, ref(q));
	produceB_thread.detach();
}
3.主线程传递给子线程的对象要用ref(),防止拷贝(特别传入孤儿线程) 4.线程之间共享的数据要加锁,而且是同一把锁 5.如果条件变量用于孤儿线程,主线程不能提前结束,要等待孤儿线程的条件变量通信完成
#include 
#include 
#include 
#include 

std::condition_variable cv;
std::mutex cv_mutex;

void wait() {
	std::cout << "waitting..." << std::endl;
	
	std::unique_lock u_lock(cv_mutex);
	
	cv.wait(u_lock);

	std::cout << "wait end" << std::endl;
}

void notify() {
	std::cout << "notifying..." << std::endl;
	std::this_thread::sleep_for(std::chrono::seconds(1));
	cv.notify_all();
	std::cout << "notified" << std::endl;
	
}

int main(){
	std::thread wait_thread(wait);
	wait_thread.detach();
	std::thread notifiy_thread(notify);
	notifiy_thread.detach();

	std::this_thread::sleep_for(std::chrono::seconds(3));
	return 0;
}

6.多个线程共享的自定义类用智能指针,而且要使用ref()防止拷贝, 7.线程处于阻塞状态时,有一定概率出现虚假唤醒,要使用while来避免 8.信号丢失问题通常出现在线程执行顺序错误 9.std::cout也是要争抢的资源 10.在共享类里面给共享数据加锁,并且要写数据时要加容错处理 11.cv.wait(u_lock,lambda),等待结束的条件是:u_lock收到notify并且lambda返回值为true,一定要两个同时满足!!!!!!!!!! 三、示例:巨多生产者和消费者同时并发
#include 
#include 
#include 
#include 

#include 

class Queue
{
    std::mutex mutex;
    std::queue q;

public:

    std::condition_variable _consume_cv;
    std::condition_variable _produce_cv;
    std::mutex _consume_mutex;
    std::mutex _produce_mutex;
    Queue() {
    }
    ~Queue() {
    };

    void pushToQueue(const char& a) {
        std::unique_lock u_lock(mutex);
        if (10000 == q.size()) return; //防止出错
        std::cout << "produce : A " << std::endl;
        q.push(a);
    }
    void popfromQueue() {
        std::unique_lock u_lock(mutex);
        if (q.empty()) return; //防止出错
        std::cout << "consume : " << q.front() << std::endl;
        q.pop();
    }

    size_t getQueueSize() {
        return q.size();
    }
    bool isEmpty() {
        return q.empty();
    }
    char getQueueFront() {
        return q.front();
    }
};


void produce(std::shared_ptr& q) {

    if (q == nullptr) {
        std::cout << "q is nullptr" << std::endl;
    }

    while (true)
    {
        //防止出错不用==
        if (10000 <= q->getQueueSize()) {
            q->_consume_cv.notify_all();
            std::unique_lock u_lock(q->_produce_mutex);
            q->_produce_cv.wait(u_lock);
        }
        q->pushToQueue('A');
        //std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

void consume(std::shared_ptr& q) {

    if (q == nullptr) {
        std::cout << "q is nullptr" << std::endl;
    }

    //std::this_thread::sleep_for(std::chrono::seconds(1));

    while (true)
    {
        if (q->isEmpty()) {
            q->_produce_cv.notify_all();
            std::unique_lock u_lock(q->_consume_mutex);
            q->_consume_cv.wait(u_lock);
        }
        q->popfromQueue();
        //std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main() {

    //初始化
    std::shared_ptr q = std::make_shared();

    std::thread producers[80];
    for (auto i = 0; i < 80; ++i)
    {
        producers[i] = std::thread(produce, ref(q));
    }
    std::thread consumers[100];
    for (auto i = 0; i < 100; ++i)
    {
        consumers[i] = std::thread(consume, ref(q));
    }


    for (auto& producer : producers)
    {
        if (producer.joinable())
            producer.join();
    }
    for (auto& consumer : consumers)
    {
        if (consumer.joinable())
            consumer.join();
    }

    return 0;
}
四、线程池
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/836588.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号