线程池网络服务模型

使用C++构建高性能网络服务 基于epoll与线程池实现的C++网络库,其中服务端采用线程间共享互斥锁避免惊群效应。详解架构设计、异步日志、支持非阻塞IO的缓冲。阅读时长约20min。 从Nginx说起 Nginx是使用多进程与IO多路复用实现的高性能C++服务端,但是Nginx为什么要使用多进程,而不是多线程呢? 子线程与子进程的主要区别在于子进程有独立的PID与地址空间,独立PID在并发编程时使得信号的处理更加方便,因为信号根据种类不同,作用于线程组时的行为也有很大的不一样。但由于父子进程各自的地址空间是独立的,所以nginx 阅读详情

前述: 线程池网络服务是针对多线程网络服务模式的不足而提出的改进模式;其基本理念是先创建一批资源,当有用户到来时,直接分配已经创建的资源;线程池的主要目的是减少系统在频繁创建资源时的开销。

线程池网络服务的实现原理:

  1>  主服务线程创建的即定数量的服务线程,同时在指定端口进行侦听;

  2>  若当前有新连接到来,则从线程池中找出空闲的服务线程,为其服务,服务完毕,线程不进行释放,重新放回线程池;

  3>   若当前线程池已经满了,则将当前的连接加入等待队列或者为其创建新的线程为其服务(依实现而定);

线程池网络服务的流程图如下:

这里写图片描述

线程池服务的优点: 性能高效

线程池的核心设计思想是: 系统在初始化时就创建一定数量的服务线程,并使它们处于空闲装态,若当前有新用户到来,则系统先查找有无空闲线程,若有则立即为其分配服务线程,若没有,则将新用户加入待服务的队列并在其他线程服务完成后,重新为其分配服务线程。

新用户若在等待服务队列里耗时过长,会影响用户体验,针对此问题,有以下的改进方案:

1> 动态创建新的服务线程,服务结束后,该线程加入到线程池,此种改进方法的好处是用户体验得到提升,但是潜在问题是线程的规模在长时间,大并发用户的状态下,会变得很大,最后会因资源消耗过大,系统退出;

2> 增加一个线程资源回收机制,当线程池的规模达到一定程度或满足某种即定规则时,会主动杀死一些线程,以达到在用户体验于系统运行稳定性之间的折中;

线程池的设计方案:

   1> 系统在初始化时,开辟THREAD_MAX个线程,组成服务线程池。

   2> 每个线程均有两种状态,空闲、工作状态,每个线程均有一块属于自己得公共数据区域,这块数据区域存放两个变量,一个是用来标记自身状态,0:空闲 1:工作,另一个变量对应客户端套接字号,如果线程处于空闲状态,则套接字号为初始值。

   3> 当有新用户到来时,系统通过查找公共数据区域,判断当前系统是否有空闲线程,若有则直接为其分配服务线程。

   4> 若当前没有空闲线程,系统将不做任何处理,提示当前系统忙,关闭新客户套接字

以下是线程池的一个示例:

//客户端代码
#include "unp.h"
void Input(Oper *op);
void help();

int main(int ac, char *av[])
{
    int sockcli = socket(AF_INET, SOCK_STREAM, 0);  //得到客户端的套接字
    if(sockcli == -1){
        perror("socket");
    }

    struct sockaddr_in addrser;   //服务器的地址结构
    addrser.sin_family = AF_INET;   //设置服务器的协议家族
    addrser.sin_port = htons(SERVER_PORT);   //设置服务器的端口号
    addrser.sin_addr.s_addr = inet_addr(SERVER_IP);   //设置服务器的IP地址

    socklen_t addrlen = sizeof(struct sockaddr);   //得到服务器的地址结构大小

    int res = connect(sockcli, (struct sockaddr*)&addrser, addrlen);   //连接服务器
    if(res == -1){
        perror("connect");
    }else{
        printf("client connect server ok.\n");
    }

    char cmd[20];   //用于存储客户所请求的服务名称
    Oper op;        //客户的请求的结构体(包括客户请求的服务类型,输入的数据)
    int result;     //由服务器发回的请求的服务结果

    //客户发送请求并接收请求结果
    while(1){
        printf("please input cmd:>");
        scanf("%s", cmd);

        if(strcmp(cmd, "add") == 0){
            op.oper = ADD;
            Input(&op);
        }else if(strcmp(cmd, "sub") == 0){
            op.oper = SUB;
            Input(&op);
        }else if(strcmp(cmd, "mul") == 0){
            op.oper = MUL;
            Input(&op);
        }else if(strcmp(cmd, "div") == 0){
            op.oper = DIV;
            while(1){
                Input(&op);
                if(op.op2 == 0){   //除数为0时重新输入
                    perror("op2 == 0 error");
                    printf("please input again.\n");
                    continue;
                }
                break;
            }
        }else if(strcmp(cmd, "help") == 0){
            help();
            continue;
        }else if(strcmp(cmd, "quit") == 0){
            op.oper = QUIT;
        }else{
            printf("your input is invalid.\n");
        }

        int res = send(sockcli, (char *)&op, sizeof(op), 0);  //发送客户的请求给服务器
        if(res == -1){
            perror("send");
        }

        if(op.oper == QUIT){
            break;
        }

        recv(sockcli, &result, sizeof(int), 0);   //接收服务器发送回来的结果
        printf("result = %d\n", result);
    }

    close(sockcli);   //关闭客户端的套接字
    return 0;
}

void Input(Oper *op)   //得到进行操作的两个数
{
    printf("please input op1 add op2.\n");
    scanf("%d, %d", &op->op1, &op->op2);
}

void help()   //提示信息
{
    printf("#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*\n");
    printf("^^^^^^^^^version^^^^^^^^^ :         ^^^^^v1.0^^^^^^^^^^\n");
    printf("^^^^^^^^^author^^^^^^^^^^ :         ^^^^^haha^^^^^^^^^^\n");
    printf("~*~*~*~*~cmd~*~*~*~*~*~*~           ~*~*~describe~*~*~\n");
    printf("~*~*~*~*~add~*~*~*~*~*~*~           ~*~*~op1 + op2~*~*\n");
    printf("~*~*~*~*~sub~*~*~*~*~*~*~           ~*~*~op1 - op2~*~*\n");
    printf("~*~*~*~*~mul~*~*~*~*~*~*~           ~*~*~op1 * op2~*~*\n");
    printf("~*~*~*~*~div~*~*~*~*~*~*~           ~*~*~op1 / op2~*~*\n");
    printf("#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*\n");
}
//服务器端的代码
#include "../unp.h"
#define THREAD_MAX 3

typedef struct thread_arg{
    bool flag;
    int sockconn;
}thread_arg;

typedef struct thread_arg threadpool[THREAD_MAX];
threadpool pool;


void* handler(void *arg)
{
    int index = *(int *)arg;
    printf("[%d] thread startup.\n", index);

    struct thread_arg *pthread = &pool[index];

    int sockconn = pthread->sockconn;

    char sendbuf[100];
    Oper op;
    int result;
    while(1)
    {
        if(pthread->flag){
            printf("[%d] thread start work.\n", index);
        int res = recv(pool[index].sockconn, (char *)&op, sizeof(op), 0);
        if(res == -1){
            perror("recv");
        }

        if(op.oper == ADD){
            result = op.op1 + op.op2;
        }else if(op.oper == SUB){
            result = op.op1 - op.op2;
        }else if(op.oper == MUL){
            result = op.op1 * op.op2;
        }else if(op.oper == DIV){
            result = op.op1 / op.op2;
        }else if(op.oper == QUIT){
            struct sockaddr_in addrcli;
            socklen_t addrlen = sizeof(struct sockaddr);
            getpeername(pool[index].sockconn, (struct sockaddr*)&addrcli, &addrlen);
            printf("client[%d] quit.\n", addrcli.sin_port);
            pthread->flag = 0;
            close(sockconn);
            continue;
        }

        send(pool[index].sockconn, (char *)&result, sizeof(int), 0);
        }else{
            printf("[%d] thread is idel.\n", index);
            sleep(1);
        }
    }
}

int main(int ac, char *av[])
{
    int sockser = socket(AF_INET, SOCK_STREAM, 0);
    if(sockser == -1){
        perror("socket");
    }
    int yes = 1;
    if(setsockopt(sockser, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
        perror("setsockopt");
    }

    struct sockaddr_in addrser, addrcli;
    addrser.sin_family = AF_INET;
    addrser.sin_port = htons(SERVER_PORT);
    addrser.sin_addr.s_addr = inet_addr(SERVER_IP);

    socklen_t addrlen = sizeof(struct sockaddr);
    int res = bind(sockser, (struct sockaddr*)&addrser, addrlen);
    if(res == -1){
        perror("bind");
    }
    listen(sockser, QUEUE_SIZE);


    pthread_t tid[THREAD_MAX];
    for(int i = 0; i < THREAD_MAX; ++i){
        pool[i].flag = 0;
        pool[i].sockconn = 0;
    }
    for(int i = 0; i < THREAD_MAX; ++i){
        pthread_create(&tid[i], NULL, handler, &i);
        sleep(1);
    }

    int sockconn;
    int j = -1;
    while(1){
        sockconn = accept(sockser, (struct sockaddr*)&addrcli, &addrlen);
        if(sockconn == -1){
            perror("accept");
        }
        printf("client[%d] connect server ok.\n", addrcli.sin_port);
        for(int i = 0; i < THREAD_MAX; ++i){
            if(pool[i].flag == 0){
                pool[i].sockconn = sockconn;
                pool[i].flag = 1;
                break;
            }
            ++j;
            if(j >= THREAD_MAX){
                pthread_create(&tid[j], NULL, handler, &j);
                pool[j].sockconn = sockconn;
                pool[j].flag = 1;
                sleep(1);
                break;
            }
        }
    }
    close(sockser);
    return 0;
}
//头文件
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>

#define SERVER_IP    "127.0.0.1"
#define SERVER_PORT  7070

#define QUEUE_SIZE   5

typedef enum{ADD, SUB, MUL, DIV, QUIT}OPER_STATE;

typedef struct Oper{
    OPER_STATE oper;
    int op1;
    int op2;
}Oper;
网络服务端开发小结(短连接、长连接、进程池、线程池)      平时对网络编程方面比较感兴趣,看了一些相关的资料,自己也尝试写过一些不同网络模型的服务程序。这次刚好有一个新的需求,需要开发一个转发服务器。之前开发的项目,网络通讯都是处理联机交易的,网络连接都是采用短连接,这次的服务端,采用长连接的方式。 1. 轮询和主动通知选择         公司有一个客户端产品(CLIENT),因为需要从多个客户的服务端获(SERVER)取信息,原有的设 阅读详情

相关推荐

C++多线程线程池服务端与客户端实战项目

看到这里,你已经掌握了构建一个高性能并发系统的完整链条:🔁 多线程基础 → 🧠 线程池设计 → 🌐 网络通信整合 → 📊 性能调优这不是纸上谈兵,而是可以直接投入使用的工业级方案。你可以基于这套架构继续拓展:添加任务优先级队列支持带返回值的任务(实现定时任务调度器集成日志、监控、配置管理模块最终,你会发现自己不仅能写出“能跑”的代码,更能设计出“可靠、可维护、可扩展”的系统级软件。而这,正是优秀工程师与普通码农之间的真正差距所在。💼💻。

weixin_36483050的博客 933

网络模型(看这一篇就够了)

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击http://www.captainbed.net 一、OSI模型 OSI 模型(Open System Interconnection Model)是一个由国际标准化组织(ISO)提出的概念模型,试图提供一个使各种不同的计算机和网络在世界范围内实现互联的标准框架。 它将计算机网络体系结构划分为七层,每层都可以提供抽象良好的接口。了解 OSI 模型有助于理解实际上互联网络的工业标准——TCP/IP 协议。 O

了解➔熟悉➔掌握➔精通 2万+

jane street market prediction 冠军方案 奇巧淫技与topline链接整理(3/3)

目录前言将income 作为loss(优化目标)读取数据,定义优化目标模型训练与微调提交结果多目标学习Topline整理AE+MLP (rank10)Current 17th solution: Ensembles of deep (49 layer) MLPsmixup augmentation: a way to learn from trades with weight=0 (rank4)My (perhaps) over-complicated LSTM solutionCurrent 62nd .

weixin_51484067的博客 2639

基于线程池的HTTP服务器(C/C++)

浏览器输入用户名密码登录注册到注册成功,返回注册成功页面底层发生了什么?想大概了解http/1.0协议底层大概如何实现的吗?这个小项目将带你了解。

我只是一个路过的老年人 1842

SDK报错(1)undefined reference to `f_mount‘

按文中说法是ff.c文件中用了一个if语句来判断是否启用ff.h头文件,但是却没有地方进行宏定义来满足这个if条件。利用SDK读取sd卡时,添加了xilffs库,而且包含了ff.h头文件,还是对fat库的函数报错。网上有的说在ARM v7 gcc linker中添加xilffs的方法可以解决,但我试了没有用。如下图,我们可以在ff.c中自己添加一个宏定义来实现这个条件。最后在赛灵思论坛找到了一个解决方法,原文连接如下。这时候保存编译之后,报错就消失了。ff.c 文件在bsp工程下。

EfunStudy的博客 1481

从“跳变”到“连续”:深入理解霍尔传感器插值与PLL角度估算的优劣与选择

本文深入解析霍尔传感器角度估算技术,对比线性插值法和锁相环(PLL)跟踪法的优劣,为电机控制领域的工程师提供实用指南。通过STM32F407和CubeMX的实例,详细探讨两种方法的实现细节、性能对比及优化策略,帮助在不同应用场景下做出最优选择。

weixin_30855761的博客 557

解读github上流行的ThreadPool源码

偶然发现github上有个ThreadPool项目(),star数居然3k+,里面也就两个文件,一个ThreadPool.h,一个example.cpp。看了一下,项目代码是cpp11写的。老实说,代码极其简洁又难懂。下面是可以看看,有个直观印象。i

az44yao的专栏 693

基于虚拟阻抗重塑的构网型VSG变流器SISO序阻抗建模与宽频振荡抑制策略分析(面向高比例新能源并网场景)

本文深入探讨了基于虚拟阻抗控制的构网型VSG变流器SISO序阻抗建模技术及其在高比例新能源并网场景中的宽频振荡抑制策略。通过虚拟阻抗重塑,有效改善了变流器的阻抗特性,解决了次/超同步频段的振荡问题,并提供了参数设计、阻抗扫频验证等实用技巧,为新能源并网系统的稳定性提供了可靠解决方案。

weixin_29268385的博客 249

c++写高性能的任务流线程池(万字详解!附完整github代码)

本文原是github开源项目MC_thread_pool的说明文档,原文发送在此,同时本文中所有代码均在github中有完整实现,查看代码请移步github仓库!

墨城的博客 3134

树莓派4B没有serial0或ttyS0,serial0没有映射到ttyS0,serial0和serial1调换映射

环境: 树莓派4B,ubuntu mate20 现象 终端输入ls -l /dev,发现只有serial1->ttyAMA0,没有serial0页没有ttyS0,更没有二者的映射。网上很多方法都是树莓派3B和3B+的,我自己试过,不太适用于4B,下面的方法是4B的,我自己用是成功的。 解决方法 cd /boot/firmware sudo gedit config.txt 注意不是/boot下的config,而是/boot/firmware下的config 打开文件后,找到enable_uart=0

qq_41208487的博客 7891

29、固态变压器拓扑、设计及其应用深度解析

本文深入解析了固态变压器(SST)的拓扑结构、设计方法及其在智能电网和能源互联网中的应用。重点探讨了机器学习在SST优化设计中的应用,包括中高频变压器设计、整体系统优化与建模研究。文章详细介绍了多端口SST的拓扑特点、功率传输机制及其作为能源路由器的关键作用,分析了不同端口数量下的控制复杂度与应用场景,并通过案例研究展示了四端口SST在分布式能源系统中的实际应用。最后,文章总结了多端口SST面临的技术挑战,并展望了未来在先进控制策略、集成化设计和标准化方面的发展方向。

study的专栏 3791

c++ 线程池/Github 开源项目源码分析(progschj/ThreadPool)

维基百科上对线程池的简要介绍:线程池(thread pool):一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。ThreadPool 项目地址是一个简易的基于 c++11 标准的线程池实现,采用了。

为啥不吃肉捏 的博客 3728

思维链:让AI更接近人类思维的技术

本文将探讨一种名为“思维链”的技术,它旨在让AI更接近人类思维。文章首先介绍了问题背景与核心概念,接着讲解了算法原理和数学模型,随后阐述了系统分析与架构设计,最后通过项目实战展示了思维链的实际应用,并提供了最佳实践和小结。思维链是一种旨在模拟人类思维过程的技术,它通过构建一系列相互关联的思维方式,实现对复杂问题的分析和解决。思维链算法是一种基于人类思维过程的人工智能算法,它通过构建一系列思维链,实现对问题的分析和解决。智能问答系统是一种常见的人工智能应用,它能够回答用户提出的各种问题。

AI天才研究院 942

C++ 网络服务端主线:从线程池到 Reactor 的完整路线图

本文介绍了C++网络服务骨架系列的学习路线。作者强调应先从基础入手,通过4篇文章逐步构建完整的服务端系统思维:首先实现单线程阻塞版TCP服务端,理解基本流程;然后将线程池接入实现请求处理;接着完善请求分发与连接管理;最后升级到Reactor模型。这条从线程池到网络连接再到并发模型的主线,旨在帮助开发者建立从"并发组件"到"服务端系统"的完整认知结构,为后续学习高并发模型打下坚实基础。

Mark Wu 的博客 1103

基于Simulink实现电动汽车制动能量回收系统的仿真

通过上述步骤,我们成功实现了基于Simulink的电动汽车制动能量回收系统的仿真研究。该系统能够全面评估制动能量回收系统的性能,验证控制策略的有效性,并通过优化设计提高能量回收效率和制动安全性。引入智能预测:结合人工智能技术,实现更智能的能量回收控制策略。扩展功能:增加对多种车型和制动场景的支持,提升系统通用性。实验验证:将仿真模型应用于实际硬件,进行实验验证,评估其在实际工况下的表现。

xiaoheshang_123的博客 336

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

高性能网络服务程序简介

网络服务程序一般分为:单线程重复式、多进程网络服务、多线程网络服务、线程池网络服务及IO多路复用。   1、单线程重复式,是一种简单的阻塞等待,侦听服务,连接,提供服务,释放,连接,服务,释放......... 若当前处于连接状态,有新的连接到达,则进入排队队列等待服务。    单线程重复式实现简单,但是确定也明显,每次只能为一个用户提供服务,若服务时间长,则对排队连接的用户体验产生不利影响。

dadidiaosu的博客 520

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Thrift 个人实战--Thrift 网络服务模型

  前言:   Thrift作为Facebook开源的RPC框架, 通过IDL中间语言, 并借助代码生成引擎生成各种主流语言的rpc框架服务端/客户端代码. 不过Thrift的实现, 简单使用离实际生产环境还是有一定距离, 本系列将对Thrift作代码解读和框架扩充, 使得它更加贴近生产环境. 本文主要讲解Thrift的高性能网络框架模型, 讲解各种网络模型的特点和区别. Thrift 高性能...

weixin_34059951的博客 188

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

线程池 线程优先级

现在维护的很多后端模块都是采用线程池模型网络服务,经常遇到一些超时等问题,在分析这类问题前先要了解epoll的多线程模型。这个模型下,监听线程负责建立网络连接,将连接放入队列; 工作线程负责从队列中取出连接,网络收发,计算。因此,响应时间取决于四个部分: 连接等待建立的时间 + 队列中的时间 + 网络IO时间 + 处理时间。 当然我们讨论的前提是CPU没有被完全耗尽的情况。当CPU完全被耗

青青的专栏--C/C++ OOA/D Design Pattern 1347

使用 C++ 编写高并发网络服务程序模型

使用 C++ 编写高并发网络服务程序模型

小桥流水 的专栏 832

Muduo 多线程模型:一个 Sudoku 服务器演变

Muduo 多线程模型:一个 Sudoku 服务器演变 分类: muduo2011-06-16 13:0224562人阅读评论(27)收藏举报 多线程服务器server网络编程string 目录(?)[+] Sudoku Solver 协议基本实现 常见的并发网络服务程序设计方案结语 陈硕 (giantchen AT gmail) blog.cs

junecauzhang的专栏 1027

C++高性能服务器开发 epoll+线程池模型

文章目录前言epoll 部分线程池部分整体设计: 前言 最近在总结之前做的恋爱交由平台的项目。在优化服务器时,将一开始使用的同步阻塞+多线程,替换为现在的epoll+线程池模型。提高了并发的能力,可以实现C10k的目标。 因此,特写此文,用来记录epoll+线程池模型。为相同需求的同学提供优化思路。 epoll 部分 首先要做的还是socket的创建,绑定,监听。并且创建epoll的句柄,同时将监听socket挂载到红黑树上,方便以后客户端有连接请求时可以建立连接。 int TcpNet::InitNe

好几个交换机吧的博客 1610

基于线程池从零实现TCP计算器网络服务

本文介绍了C++中封装线程安全工具的实现方法。第一部分封装了RAII风格的互斥锁,通过Mutex类管理原生锁资源,使用LockGuard类实现自动加解锁,避免了手动管理锁资源带来的死锁风险。第二部分封装了线程池,通过Thread类将C风格的线程接口转化为面向对象形式,利用静态成员函数作为跳板解决C与C++函数签名不匹配的问题。重点讲解了如何通过引用传递确保锁的有效性,以及如何通过this指针在静态函数中访问对象成员。这些封装提高了多线程编程的安全性和易用性,让编译器自动管理资源生命周期,减少了常见并发问题的

Vect__的博客 837

TCP服务器并发编程实践:多进程模型与线程池应用

关键点在于backlog参数设置,它决定了未完成连接队列的容量,直接影响服务器的并发连接处理能力。通过fork创建子进程处理客户端请求时,采用"孙子进程"技巧避免僵尸进程:首次fork的子进程立即再次fork后退出,使孙子进程被init进程接管。这种方式省去了显式的进程回收操作,同时父进程需要及时关闭已分发的客户端文件描述符以防止资源泄漏。后者更灵活,允许直接复用现有的Service方法。特别是调试多进程程序时,平台提供的终端监控功能能清晰展示进程关系变化,对于理解守护进程的创建过程很有帮助。

MoonstoneTiger89的博客 851

C++ 高性能网络服务骨架(四)—— 从阻塞模型到 Reactor:服务端并发模型进阶

本文探讨如何用更少线程处理更多连接,突破传统"一个连接一个线程"的瓶颈。首先分析三种模型:单线程阻塞(串行处理)、线程池+阻塞IO(线程被占用)、服务骨架(仍使用阻塞IO)。核心问题在于线程被阻塞,解决方案是采用非阻塞IO配合epoll事件通知机制,实现从"线程绑定连接"到"线程绑定事件"的转变。文章详细介绍了epoll工作原理和Reactor事件驱动模型,指出高并发的本质在于调度方式而非线程数量。最终形成完整认知闭环:线程池解决执行问题,epol

Mark Wu 的博客 410

多线程程序与单进程程序的架构

多线程程序和单进程程序中都有使用,在网络服务中都有使用。多线程程序主要用于同步的处理一些请求,为了在同一时间处理较多的请求。一般采取线程池的策略,一个主线程来分配请求。 (一)常见的进程模型: (1)多线程模型 这种模式固定线程数量,吞吐量是接近每个线程的吞吐量*线程数。不具有伸缩性,伸缩性不强,在高负载下能力有很大限制。对于负载不大的情况下的同步数据访问应用还是

lijunlinlijunlin的专栏 529
上一篇: 多线程网络服务的一般模型
下一篇: TCP的三次握手过程图解
lm_123_456
博客等级 码龄11年 35粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值