自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(38)
  • 资源 (1)
  • 收藏
  • 关注

原创 闲鱼监控软件

闲鱼监秒拍控软件可以根据您的需求,在您设定的价格范围内监控货架上的产品,相当于一个筛选闲鱼信息的工具,可以帮助您准确锁定卖家,尤其是专门做闲鱼生意的卖家。当你设定的目标出现时,它会帮助你自动抢购,让你再也不用担心低价好卖的产品被抢占。闲鱼监控助手是一款闲鱼出品的多关键字搜索工具应用。这个应用总体还是挺有用的,在闲鱼上找二手其实也挺有意思的。闲鱼监控助手可以方便的添加你想要关注的闲鱼内容,自动帮你搜索。给老婆做了个闲鱼价格监控,当价格发生波动时自动邮件通知。用微信的邮件提醒可以直接查看追踪。

2023-11-24 21:27:31 800 2

原创 Mac App 不发布App Store 网页下载安装公证流程,解决不提示“来自身份不明开发者”

不公证的话,用户安装app,会提示来自不明开发者,需要按住ctrl +双击才能打开程序。Mac app 公证。

2023-08-30 14:41:18 203

原创 TCP多进程并发服务器与单进程客户端(简单回声)echo clinet

【代码】TCP多进程并发服务器与单进程客户端(简单回声)echo clinet。

2023-08-04 18:32:08 200

原创 TCP单进程循环服务器与单进程客户端(简单回声)echo server

【代码】TCP单进程循环服务器与单进程客户端(简单回声)echo server。

2023-08-04 18:17:43 227

原创 muduo网络库示例(高效率多线程异步日志)

多线程程序日志库要求线程安全,即多个线程可以并发写日志,两个线程的日志消息不会出现交织。线程1写入:ABCDEFG,线程2写入 abcdefg。出现ABCDabcEFGdefg 这就是出现交织。用一个全局的mutex保护IO,全局mutex 会造成全部线程抢占一个锁。相当于所有并发写的线程变成了串行每个线程单独写一个日志文件。这种情况有可能让业务线程阻塞在写磁盘操作上。写磁盘操作相对来说耗时,就会出现写业务线程阻塞在写操作上面,影响业务线程的并发能力muduo库采用的办法是:用一个背

2022-02-24 22:01:42 16

原创 muduo网络库示例 (限制并发数和踢掉空闲连接)

限制服务器最大并发连接数(MuduoManual.pdf P108)这个比较简单,在连接里面判断最大数量断开连接。void EchoServer::onConnection(const TcpConnectionPtr& conn){ LOG_INFO << "EchoServer - " << conn->peerAddress().toIpPort() << " -> " << conn-&gt

2022-02-24 15:41:56 596

原创 muduo网络库示例(聊天服务器)

聊天服务器(MuduoManual.pdf P66)examples/asio/chat/server.cc 单线程examples/asio/chat/server_threaded.cc,多线程TcpServer,并用mutex来保护共享数据mutexexamples/asio/chat/server_threaded_efficient.cc,借shared_ptr实现copy-on-write的手法来降低锁竞争examples/asio/chat/server_threaded_hi

2022-02-24 11:30:39 1049

原创 muduo库http源码分析

http requestHTTP请求包含:request line + header + body (header分为普通报头,请求报头与实体报头) header与body之间有一空行(CRLF)请求方法有: Get, Post, Head, Put, Delete等 协议版本1.0、1.1常用请求头Accept:浏览器可接受的媒体(MIME)类型;Accept-Language:浏览器所希望的语言种类Accept-Encoding:浏览器能够解码的编码方法,如gzip,deflat

2022-02-23 14:54:46 921

原创 muduo库net源码分析十三(tcp客户端的支持)

Connector 主动发起连接带有自动重连功能#ifndef MUDUO_NET_CONNECTOR_H#define MUDUO_NET_CONNECTOR_H#include <muduo/net/InetAddress.h>#include <boost/enable_shared_from_this.hpp>#include <boost/function.hpp>#include <boost/noncopyable.hpp&gt

2022-02-23 11:36:07 127

原创 muduo库net源码分析十二(完善TcpConnection)

增加WriteCompleteCallback应用层缓冲区数据全部发送到内核缓冲区后,回调WriteCompleteCallback,以使应用层发送更多的数据。对于大流量的应用才需要关注,大流量不断生成数据,然后发送conn->send(),如果对等方接收不及时,收到通告窗口的控制,内核发送缓冲不足,这个时候就会将用户数据添加到应用层发送缓冲区(output buffer),可能会撑爆output buffer。解决办法就是,调增发送频率,关注WriteCompleteCallback 回调,

2022-02-23 10:04:40 175

原创 muduo库net源码分析十一(应用层缓冲区Buffer设计)

为什么需要有应用层缓冲区?muduo网络库使用IO复用,并且文件描述符使用非阻塞模式,如果使用阻塞模式那么read、write就会阻塞在这些系统调用之上,这样一来即使其他文件描述符的IO到来也不能立刻去处理,也就不能最大限度的使用IO线程。考虑一个常见场景:程序想通过 TCP 连接 发送 100k 字节的数据,但是在 write() 调用中,操作系统只接受了 80k 字节(受 TCP advertised window 的控制,细节见 TCPv1),你肯定不想在原地等待,因为不知道 会等多久(取决于

2022-02-22 23:08:30 386

原创 muduo库net源码分析十(muduo库如何支持多线程)

muduo库如何支持one loop per thread由以下类实现EventLoopThread(IO线程类)EventLoopThreadPool(IO线程池类)IO线程池的功能是开启若干个IO线程,并让这些IO线程处于事件循环的状态#ifndef MUDUO_NET_EVENTLOOPTHREADPOOL_H#define MUDUO_NET_EVENTLOOPTHREADPOOL_H#include <muduo/base/Condition.h>#inc

2022-02-22 15:50:25 137

原创 muduo库net源码分析九(TcpConnection生存期管理)

第5步,在TcpSever中removeConnection 移除掉TcpConnection, 正常应该在移除后销毁掉TcpConnection,但是不能销毁,如果现在销毁了TcpConnection的Channel对象也就跟着销毁了 ,而这时调用Channel的handleEvent() 函数,就会出现core down,所以说TcpConnection 的生命期应该长于Cannel对象。当连接到来,创建一个TcpConnection对象,立刻用share_ptr 来管理,引用计数为1,在C..

2022-02-22 15:07:54 173

原创 muduo库net源码分析八(TcpServer/TcpConnection)

Acceptor类的主要功能是socket、bind、listen 一般来说,在上层应用程序中,我们不直接使用Acceptor,而是把它作为TcpServer的成员 TcpServer还包含了一个TcpConnection列表 TcpConnection与Acceptor类似,有两个重要的数据成员,Socket与Channel。#ifndef MUDUO_NET_TCPSERVER_H#define MUDUO_NET_TCPSERVER_H#include <muduo/bas.

2022-02-22 11:50:59 158

原创 muduo库net源码分析七(Socket 封装)

Acceptor用于accept(2)接受TCP连接Acceptor的数据成员包括Socket、Channel,Acceptor的socket是listening socket(即server socket)。Channel用于观察此socket的readable事件,并回调Accptor::handleRead(),后者调用accept(2)来接受新连接,并回调用户callback。Acceptor 示例void newConnection(int sockfd, const InetAd

2022-02-22 10:52:31 115

原创 muduo库net源码分析六(Socket 封装)

SocketsOps.h/ SocketsOps.cc封装了socket相关系统调用(全局函数,位于muduo::net::sockets名称空间中)。Socket.h/Socket.cc(Socket类)用RAII方法封装socket file descriptor。InetAddress.h/InetAddress.cc(InetAddress类)网际地址sockaddr_in封装Endian.h封装了字节序转换函数(全局函数,位于muduo::net::sockets名..

2022-02-22 10:36:35 301

原创 muduo库net源码分析五(EventLoopThread 封装)

为什么要封装EventLoopThread?任何一个线程,只要创建并运行了EventLoop,都称之为IO线程。一个程序可以有多个IO线程,因此 IO线程不一定是主线程。muduo并发模型one loop per thread + threadpool 。一个线程有且只有一个EventLoop,一个程序可以有多个IO线程,这些IO线程可以用IO线程池来管理。这里有两个线程池,一个IO线程池一个计算线程池主要用于计算任务。IO线程也可以执行计算任务,EventLoop中的runInLoop() 可

2022-02-21 21:22:30 125

原创 muduo库net源码分析四(线程唤醒)

线程唤醒方法一个线程如何通知另一个等待中的线程,可以有三个方法:1、pipe 管道有一对文件描述符。pipe[0] 对应管道的读端,pipe[1] 对应管道的写端,等待的线程关注pipe[0]的读端,通知线程向pipe[1] 写入数据,pipe[0] 就变的可读了,等待线程获得通知就唤醒线程。2、socketpair 和管道一样有一对文件描述符,不同的是可以双向通信。3、eventfd。等待线程监听文件描述符可读事件,通知线程只要往这个线程写入数据,等待线程就会获得通知。是一个比 pipe

2022-02-21 17:11:22 477

原创 muduo库net源码分析三(定时器)

让EventLoop 能够处理定时器事件定时函数用于让程序等待一段时间或安排计划任务:sleepalarm usleepnanosleepclock_nanosleepgetitimer / setitimertimer_create / timer_settime / timer_gettime / timer_deletetimerfd_create / timerfd_gettime / timerfd_settime 选择这种方法。为什么选择timerfd_c

2022-02-21 14:27:07 193

原创 muduo库net源码分析二(类之间的关系)

muduo 网络库相关的类图白色部分是外部类,对外可见的。灰色部分是内部类,对外不可见。EventLoop是对事件的抽象Poller 是对IO 复用的抽象,有两个派生类,PollPoller 对poll 的封装,EPollPoller对epoll的封装 。这个地方是muduo 唯一使用面向对象封装的。Channel 是对IO事件的注册和响应的封装 。Channel 的Update成员函数负责注册和更新IO的可读可写等事件。Channel 的handleEvent()成员函数是对所发生的IO事

2022-02-21 09:29:47 270

原创 muduo库net源码分析一(网络编程本质)

TCP网络编程最本质的是处理三个半事件1、连接建立:服务器accept(被动)接受连接,客户端connect(主动)发起连接。2、连接断开:主动断开(close、shutdown),被动断开(read返回0)。3、消息到达:文件描述符可读。4、消息发送完毕:这算半个。对于低流量的服务,可不必关心这个事件,这里的发送完毕是指数据写入操作系统缓冲区,将由TCP协议栈负责数据的发送与重传,不代表对方已经接收到数据。对于高流量的程序,应用要在发送完毕后再发送,以免数据丢包。一个套接字有两个缓冲区

2022-02-20 22:29:01 1578

原创 多线程与并发服务器设计

第一种、循环式/迭代式服务器每处理完一个请求就关闭连接,这种模式称为短连接。循环式服务器只能够使用短连接,而不能够使用长连接。如果是长连接,处理完一个请求,write完不关闭连接而是循环到read这里接受下一个请求。而整个程序是一个单线程的程序,如果另一个程序请求过来就不能接受请求了,只能处理一个程序。要想处理多个客户端只能够短连接。这种服务器不是真正意义上的并发服务器,decode、compute、encode 不能处理太长,如果太长就会影响其他连接的响应时间。这个程序是单线程的程序,不能利用多核

2022-02-20 21:07:09 1843

原创 muduo库base源码分析十一 (日志类封装)

日志的作用开发过程中:1、有助于调试错误。实际上C/C++程序员很少使用GDB调试错误,更多的是使用日志调试错误,程序错误,分为编译时错误和运行错误。对于编译时错误编译器可以帮我们发现错误,对于运行时错误比如调用某个库函数或者系统调用出现的错误,我们可以把errno 所对应的错误信息记录到日志当中,这样我们就可以分析日志找出错误所在。如果是运行时的逻辑错误,用GDB调试的话就像大海捞针很难定位错误的位置,特别是代码量多的时候调试更加麻烦。 如果我们把整个程序运行状态都记录到了日志当中,那么通过分

2022-02-16 13:52:47 409

原创 muduo库base源码分析十 (线程本地存储单例类封装)

ThreadLocalSingleton<T>封装每一个线程都有一个T类型的单例对象指针类型是POD类型,用__thread 修饰。// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)#ifndef MUDUO_B

2022-02-15 18:57:30 427

原创 muduo库base源码分析八 (线程安全的单例类实现)

线程安全的单例类实现这个对象能够保证一个函数只能被执行一次init() 在内部创建了对象,destroy() 在内部销毁了对象// Use of this source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)#ifndef MUDUO_BASE_SINGL

2022-02-15 15:25:12 108

原创 muduo库base源码分析九 (线程本地存储)

ThreadLocal<T> 封装在单线程程序中,我们经常要用到"全局变量"以实现多个函数间共享数据。在多线程环境下,由于数据空间是共享的,因此全局变量也为所有线程所共有。但有时应用程序设计中有必要提供线程私有的全局变量,仅在某个线程中有效,但却可以跨多个函数访问。POSIX线程库通过维护一定的数据结构来解决这个问题,这个些数据称为(Thread-specific Data,或 TSD)。线程特定数据也称为线程本地存储TLS(Thread-local storage)对于

2022-02-15 13:49:24 210

原创 muduo库base源码分析七 (线程实现)

ThreadPool 实现,线程池本身也是一个生产者消费者问题线程池顾名思义,内部创建了若干线程,维护了一个线程队列,这些线程是执行任务的,所以线程池内部还维护一个任务队列。外部线程可以往线程池中的任务队列添加任务,那么这些外部线程就是生产者线程。一旦任务队列中有任务就唤醒线程队列中的线程执行这些任务,那么这些线程队列中的线程就是消费者线程。明白这点我们就很容易实现一个线程池。muduo 库中的线程池实现 ,这线程池是固定线程池,内部的线程个数是固定的,不能够自动伸缩的。cond 是一个信.

2022-02-15 11:47:03 375

原创 muduo库base源码分析六 (缓冲区实现)

BlockingQueue<T> 无界缓冲区BoundedBlockingQueue<T> 有界缓冲区这实际上是一个生产者消费者问题生产者消费者正确的访问队列,需要使用条件变量或者信号量。size 队列的大小是sizesemFull(size) 信号量,初始值等于 size,表示初始状态队列是空的。可以生产的产品数量等于size。semEmpty(0) 信号量,表示初始状态队列是空的,可以消费的产品数量等于0;mutex 多个生产者消费者要访问queu

2022-02-14 18:01:17 257

原创 muduo库base源码分析五 (进程间通信封装)

MutexLock/MutexLockGuard 互斥锁Condition 条件变量CountDownLatch 倒计时门闩类MutexLockGuard 更常用这种情况如果条件满足,就return了,忘记解锁。MutexLock mutex;void f(){ mutex.lock(); ... if(条件) { retutn; } mutex.unlock();}如果改成这样,就可以解决忘记解锁的问

2022-02-14 16:09:31 231

原创 muduo库base源码分析四 (线程封装)

线程标识符:我们知道Linux每一个进程都有一个pid,类型pid_t ,由getpid() 来获得。Linux下的POSIX 线程也有一个id,类型pthread_id ,由pthread_self() 取得,该id 是线程库维护,其id 空间是各个进程独立的(即不同进程中的线程可能有相同的id)。Linux中的POSIX线程库实现的线程其实也是一个进程(LWP),只是该线程与主进程(启动线程的进程)共享一些资源而已,比如代码段、数据段等。有时候我们可能需要知道线程的真实pid。比如进程P1要向另外一

2022-02-14 14:51:49 357

原创 muduo库base源码分析三 (Exception类)

类结构图message 保存异常信息的字符串stack_ 异常发生的时候,调用栈的回溯信息fillStackTrace() 私有函数,在构造函数中调用,用来记录异常发生时,栈回溯的信息。backtrace ,栈回溯,保存各个栈帧的地址。数组指针,数组元素是函数地址。backtrace_sympols 函数地址,转换成函数字符串。指针数组。指针数组需要调用者来释放。示例:#include <muduo/base/Exception.h>#include <

2022-02-13 23:33:11 396 1

原创 muduo库base源码分析二 (原子性操作AtomicIntegerT类封装)

为什么需要原子性操作?我们考虑这样一种场景,两个线程对同一个变量同时x++操作。x++ 在计算机的步骤:从内存中读取x的值到寄存器中,对寄存器加1,再把新值写回x所处的内存地址。假设有如下时序图:​两个线程运行结束后,x等于11,正确应该是12,那要得出正确的结果,有两个方法:第一种是锁:在X++ 之前加一把锁,加完解锁。这样就可以保证在同一时刻只有一个线程进入临界区域,对X进行读的操作,写的操作,当一个线程进入这个临界区域的时候,其他线程就不能访问这个临界区的资源,只能等到占用的线

2022-02-13 21:45:36 226

原创 muduo库base源码分析一 (Tiemstamp类封装)

muduo库的使用手册Muduo 的目录结构如下。muduo/base 目录是一些基础库,都是用户可见的类,内容包括Timestamp 类的封装Timestamp 继承至两个类muduo::copyable 空基类,起到标识作用,值类型可以拷贝的。对象有两种语义:值语言:可以拷贝的,拷贝之后与原对象脱离关系对象语义:要么是不能拷贝的,要么是可以拷贝,拷贝之后与原对象仍然存在一定关系,比如共享底层资源(要实现自己的拷贝构造函数)muduo库当中的类对象,大部分都

2022-02-11 16:24:53 454

原创 muduo库介绍

muduo库是一个多线程服务器开发库muduo 作者陈硕,现在在美国加州硅谷某互联网大公司工作,从事大规模分布式的可靠系统工程。这个库是作者多年工作的总结,可以说大家学通了这个库,找一份Linux服务器开发的工作是没问题的,因为这个库是教大家Linux环境下多线程服务器开发的正规做法,这个库是用的现在C++技术,大量使用了智能指针,bind、function这些技术。作者还出了一本书《Linux多线程服务端编程:使用muduo C++网络库》,但是这本书不适合初学者,适合具有一定网络编程经验的开发者

2022-01-28 17:04:44 11206 1

原创 网络I/O复用之epoll

epoll 用要的相关函数#include <sys/epoll.h>int epoll_create(int size);int epoll_create1(int flags);int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);t

2022-01-28 15:38:34 854

原创 网络I/O复用之poll

Linux 中的I/O复用模型有三种:select、poll、epoll。前面两种在内核中的处理方式是类似的,第三种效率最高。poll函数原型#include <poll.h>int poll(struct pollfd *fds,nfds_t nfds,int timeout);struct pollfd { int fd; /* file descriptor */ short events; /* requested events

2022-01-28 13:40:00 1395

原创 大型网站架构演变过程

大型网站架构是高并发服务器的典型实例,通过这个实例更好的理解服务器架构设计。Step1 Web Server 与数据库分离刚开始访问量少,web 服务器可以和数据库部署在同一台机器之上。这里的web server 是包含Http server + App server 。这个架构简单,但是存在的问题是Web server 和数据库相互影响,任何一个出现瓶颈都会影响网站整体访问速度,因此为了提高访问速度,可以把这两个分离开来,让他们部署在独立的机器之上。这里web server 还可以

2022-01-28 08:54:24 222

原创 大并发服务器架构

一、服务器设计目标1、高性能(High Preormance):是指对大量的并发请求,能做出快速的响应,这就要求我们的服务器能够最大程度发挥机器的性能,使机器在满负荷的情况下,尽可能多的处理并发请求,并且能及时快速的做出响应。2、高可用(High Availability):指的是服务器能够7x24小时不间断的提供服务,如果服务器出现了故障,也能够快速的转换到备用机,让备用机工作起来,而不需要人工的干预。这叫failover故障转移。3、伸缩性(Scalability): 指的是服务器具有良好的

2022-01-26 23:58:27 6677

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除