muduo网络库学习之MutexLock类、MutexLockGuard类、Condition类、CountDownLatch类封装中的知识点

本文主要是介绍muduo网络库学习之MutexLock类、MutexLockGuard类、Condition类、CountDownLatch类封装中的知识点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、MutexLock 类

class  MutexLock  :  boost::noncopyable

二、MutexLockGuard类

class  MutexLockGuard  :  boost::noncopyable


三、Condition类

class  Condition  :  boost::noncopyable


某个线程:
加锁                                    
while (条件)
wait(); //1、解锁;2、等待通知;3、得到通知返回前重新加锁
解锁

另一个线程:
加锁
更改条件
通知notify(可以移到锁外)
解锁

四、CountDownLatch类

class  CountDownLatch  :  boost::noncopyable

既可以用于所有子线程等待主线程发起 “起跑”
也可以用于主线程等待子线程初始化完毕才开始工作

下面写两个程序测试一下CountDownLatch 的作用:

CountDownLatch_test1:
C++ Code 
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
#include <muduo/base/CountDownLatch.h>
#include <muduo/base/Thread.h>

#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <string>
#include <stdio.h>

using  namespace muduo;

class Test
{
public:
    Test( int numThreads)
        : latch_( 1),
          threads_(numThreads)
    {
         for ( int i =  0; i < numThreads; ++i)
        {
             char name[ 32];
            snprintf(name,  sizeof name,  "work thread %d", i);
            threads_.push_back( new muduo::Thread(
                                   boost::bind(&Test::threadFunc,  this), muduo::string(name)));
        }
        for_each(threads_.begin(), threads_.end(), boost::bind(&Thread::start, _1));
    }

     void run()
    {
        latch_.countDown();
    }

     void joinAll()
    {
        for_each(threads_.begin(), threads_.end(), boost::bind(&Thread::join, _1));
    }

private:

     void threadFunc()
    {
        latch_.wait();
        printf( "tid=%d, %s started\n",
               CurrentThread::tid(),
               CurrentThread::name());



        printf( "tid=%d, %s stopped\n",
               CurrentThread::tid(),
               CurrentThread::name());
    }

    CountDownLatch latch_;
    boost::ptr_vector<Thread> threads_;
};

int main()
{
    printf( "pid=%d, tid=%d\n", ::getpid(), CurrentThread::tid());
    Test t( 3);
    sleep( 3);
    printf( "pid=%d, tid=%d %s running ...\n", ::getpid(), CurrentThread::tid(), CurrentThread::name());
    t.run();
    t.joinAll();

    printf( "number of created threads %d\n", Thread::numCreated());
}



执行结果如下:

simba@ubuntu:~/Documents/build/debug/bin$ ./countdownlatch_test1
pid=2994, tid=2994
pid=2994, tid=2994 main running ...
tid=2997, work thread 2 started
tid=2997, work thread 2 stopped
tid=2996, work thread 1 started
tid=2996, work thread 1 stopped
tid=2995, work thread 0 started
tid=2995, work thread 0 stopped
number of created threads 3
simba@ubuntu:~/Documents/build/debug/bin$ 

可以看到其他三个线程一直等到主线程睡眠完执行run(),在里面执行latch_.countDown() 将计数减为0,进而执行notifyall 唤醒后,才开始执行下来。


CountDownLatch_test2:
C++ Code 
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
#include <muduo/base/CountDownLatch.h>
#include <muduo/base/Thread.h>

#include <boost/bind.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <string>
#include <stdio.h>

using  namespace muduo;

class Test
{
public:
    Test( int numThreads)
        : latch_(numThreads),
          threads_(numThreads)
    {
         for ( int i =  0; i < numThreads; ++i)
        {
             char name[ 32];
            snprintf(name,  sizeof name,  "work thread %d", i);
            threads_.push_back( new muduo::Thread(
                                   boost::bind(&Test::threadFunc,  this), muduo::string(name)));
        }
        for_each(threads_.begin(), threads_.end(), boost::bind(&muduo::Thread::start, _1));
    }

     void wait()
    {
        latch_.wait();
    }

     void joinAll()
    {
        for_each(threads_.begin(), threads_.end(), boost::bind(&Thread::join, _1));
    }

private:

     void threadFunc()
    {
        sleep( 3);
       printf( "tid=%d, %s started\n" ,
               CurrentThread::tid(),
               CurrentThread::name());

        latch_.countDown();
     

        printf( "tid=%d, %s stopped\n",
               CurrentThread::tid(),
               CurrentThread::name());
    }

    CountDownLatch latch_;
    boost::ptr_vector<Thread> threads_;
};

int main()
{
    printf( "pid=%d, tid=%d\n", ::getpid(), CurrentThread::tid());
    Test t( 3);
    t.wait();
    printf( "pid=%d, tid=%d %s running ...\n", ::getpid(), CurrentThread::tid(), CurrentThread::name());
    t.joinAll();

    printf( "number of created threads %d\n", Thread::numCreated());
}



执行结果输出如下:

simba@ubuntu:~/Documents/build/debug/bin$ ./countdownlatch_test2
pid=4488, tid=4488
tid=4491, work thread 2 started
tid=4491, work thread 2 stopped
tid=4490, work thread 1 started
tid=4490, work thread 1 stopped
tid=4489, work thread 0 started
pid=4488, tid=4488 main running ...
tid=4489, work thread 0 stopped
number of created threads 3

可以看出当其他三个线程都启动后,各自执行一次 latch_.countDown(),主线程wait() 返回继续执行下去。


参考:
muduo manual.pdf
《linux 多线程服务器编程:使用muduo c++网络库》

这篇关于muduo网络库学习之MutexLock类、MutexLockGuard类、Condition类、CountDownLatch类封装中的知识点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/501647

相关文章

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Linux网络配置之网桥和虚拟网络的配置指南

《Linux网络配置之网桥和虚拟网络的配置指南》这篇文章主要为大家详细介绍了Linux中配置网桥和虚拟网络的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、网桥的配置在linux系统中配置一个新的网桥主要涉及以下几个步骤:1.为yum仓库做准备,安装组件epel-re

Java 的 Condition 接口与等待通知机制详解

《Java的Condition接口与等待通知机制详解》在Java并发编程里,实现线程间的协作与同步是极为关键的任务,本文将深入探究Condition接口及其背后的等待通知机制,感兴趣的朋友一起看... 目录一、引言二、Condition 接口概述2.1 基本概念2.2 与 Object 类等待通知方法的区别

python如何下载网络文件到本地指定文件夹

《python如何下载网络文件到本地指定文件夹》这篇文章主要为大家详细介绍了python如何实现下载网络文件到本地指定文件夹,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下...  在python中下载文件到本地指定文件夹可以通过以下步骤实现,使用requests库处理HTTP请求,并结合o

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

一文详解如何在Vue3中封装API请求

《一文详解如何在Vue3中封装API请求》在现代前端开发中,API请求是不可避免的一部分,尤其是与后端交互时,下面我们来看看如何在Vue3项目中封装API请求,让你在实现功能时更加高效吧... 目录为什么要封装API请求1. vue 3项目结构2. 安装axIOS3. 创建API封装模块4. 封装API请求

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen