【Linux】高性能服务器编程(一)——多进程/多线程和进程池/线程池

如何实现同一时刻能与多个客户端同时交互?我们希望是服务器与多个客户端交互以并发进行处理。在我们高性能服务器编程下有这样几种方法,一是多进程/多线程,二是进程池/线程池,三是I/O复用。

目录

一、多进程/多线程

(一)多进程

(二)多线程:启动多个线程,每个线程执行和一个客户端交互的程序;

(三)两者的选择和比较

1、多进程和多线程的选择

2、多进程/多线程实现并发的缺陷:

二、进程池/线程池

(一)概念明确

(二)进程池/线程池的设计思想

1、进程池创建:

2、线程池创建:

(三)进程池/线程池的工作流程

(四)线程池的实现结果展示:

(五)两者比较

         1、两者选择

         2、缺陷:

         3、线程池实现难点


文将介绍前两种多进程/多线程,进程池/线程池。

一、多进程/多线程

(一)多进程

启动多个进程,每个进程执行和一个客户端交互的程序;父进程完成与客户端的连接工作,完成后,创建子进程,子进程与客户端具体交互。

多进程实现服务器和客户端的并发交互具体流程:父进程接收客户端的连接,在父进程的PCB结构中记录所连接的文件描述符c(有限的个数,一般够用),当父进程接收到客户端的连接之后,创建子进程,在子进程创建的时候,会复制父进程的PCB结构,它们会指向同一个地址空间,然后让子进程与客户端进行具体的交互。当子进程和客户端通讯结束后,关闭c,并没有实际关闭,父进程必须显示关闭连接,这样才真正的关闭。

在Linux下实现的简单多进程交互的结果:

通过命令:netstat -natp 显示网络相关信息,可以看到当前的连接状态:

注意:

(1)子进程是否能访问c,——》能访问并且是浅拷贝父进程   

(2)子进程关闭c,父进程并没有关闭 ——》父子进程都必须显式关闭c。

(二)多线程:启动多个线程,每个线程执行和一个客户端交互的程序;

主线程只负责接受客户连接,创建函数线程,函数线程负责通讯。

函数线程如何获取到与客户的连接文件描述符?创建线程时,以值传递的方式将连接的文件描述符传递给函数线程。不能使用地址传递。

             主线程是否需要关闭文件描述符?主线程不需要关闭文件描述符,同一个进程中所有线程共享进程资源,仅有独立的栈区。

僵死进程——不需要,本身不会产生子进程,只有函数线程;

注意:

(1)函数线程是否能够访问c,--》能访问 打开的文件描述符资源时属于进程的。

(2)函数线程关闭c,链接已经断开。

(三)两者的选择和比较

1、多进程和多线程的选择

根据不同业务,不同的场景需求进行选择。

多进程和多线程的比较:

         (1)从编程角度:多线程代码实现相对于进程而言简单,控制也简单;

         (2)从占据资源:多进程比多线程大

         (3)切换:线程的切换比进程的切换快;

       (4)资源共享:线程比进程间共享资源多,线程共享全局,堆,文件等资源。所以还需要考虑线程安全性问题;进程间是独立的,不需要考虑安全性问题。

        (5)从能够创建的数量:多进程比多线程要多很多;一个进程最多能够创建的线程是有限的;差不多300多。

2、多进程/多线程实现并发的缺陷:

(1)每个客户端连接上后,服务器都需要创建进程或线程;

(2)创建的进程或线程只为一个客户端服务于,服务完成后就会被释放,造成服务器资源浪费;

(3)一台机器上能创建的进程或线程是有限的;

二、进程池/线程池

(一)概念明确

池:提前申请的大量资源存放的一个单位;程序启动时,将需要的子进程或函数线程创建好,服务器程序结束时,这些进程或线程才会被释放。用池的概念将其维护;

内存池:使用内存之前先申请大量的内存,当后序需要使用时,直接从内存池中分配,而不需要通过系统分配。

进程池:进程池是由服务器预先创建的一组子进程;

线程池:线程池是由主线程预先创建的一组线程;

(二)进程池/线程池的设计思想

在服务器程序启动时,创建出多个进程或多个线程,将其维护在池中。当有客户连接时,就从池中分配进程或线程为客户端服务。一次创建的个数于操作系统的处理能力有关。

主线程或父进程主要负责与客户端连接;而函数线程或子进程与特定客户端进行交互。

1、进程池创建:

(1)在程序启动时,创建多个进程,将子进程维护在进程池中;

(2)进程池中的进程必须阻塞在获取客户端文件描述符之前

(3)主进程负责接收客户连接,并将获取到的客户连接文件描述符传递给进程池中的进程;必须借助于进程间通讯,不能仅仅传递c值,传递的是文件描述符。

(4)主进程通过某种机制唤醒进程池中的某个子进程来为特定的一个客户端进行服务;

2、线程池创建:

(1)程序启动 网络基础

(2)创建线程 线程是循环执行的,线程必须是阻塞在一条件上

(3)主线程通过线程下放选择一个子线程来执行任务;

(3)主线程接收客户连接并且在线程池中唤醒一个线程来为此客户服务;

注意:

线程池中线程的数量是有有限的,如何维护一个等待队列;

一个进程或者一个线程经常阻塞在i/o操作;

(三)进程池/线程池的工作流程

进程池的工作流程完全可以用到线程池中,因此我们只从一个出发来进行探讨:

进程池是由服务器预先创建的一组子进程,这些子进程的数目在3~10个之间。进城池中的所有子进程都运行着相同的代码,并且具有相同的属性,比如优先级,PGID等。

         当有新的任务到来时,主进程将通过某种方式选择进程池中的某一个子进程来为之服务。相比与动态创建子进程,选择一个已经存在的子进程的代价显然要小的多。

         主进程选择哪个子进程来为新的任务服务,有两种方式:

         主进程使用某种算法 来主动选择子进程。最简单最常用的是随机算法和Round Robin轮流选取算法,但更优秀的算法将会使得任务在各个工作进程中更加均匀的分配,从而减轻服务器的整体压力。

         主进程和所有子进程通过一个共享的 工作队列来同步,子进程都睡眠在该工作队列上。当有新的任务到来时,主进程将任务添加到工作队列中。这将唤醒正在等待任务的子进程,不过只有一个子进程将获得新任务的“接管权”,他可以从工作队列中选取出任务并执行之,而其他子进程将继续睡眠在工作队列中。

         当选择好子进程后,主进程还需要使用某种通知机制来告诉目标子进程有新的任务需要处理,并传递必要的数据。最简单的方法就是在父进程和子进程之间预先建立好一条管道,然后通过管道来实现所有的进程间通信。在主线程个子线程之间传递数据就要简

(四)线程池的实现结果展示:

通过线程池实现多并发操作,服务器可以同时接收多个客户端发来的消息并且进行处理。

(五)两者比较

         1、两者选择

          (1)从占据资源:多进程比多线程大

          (2)切换:线程的切换比进程的切换快;

          (3)资源共享:线程比进程间共享资源多,线程共享全局,堆,文件等资源。所以还需要考虑线程安全性问题;进程间是独立的,不需要考虑安全性问题。

         2、缺陷:

         (1)启动时给某一进程池创建进程,创建进程的个数于主机环境有关。

         (2)启动时在进程中创建线程,线程的创建个数也是有限的,大约300多;

         3、线程池实现难点

          (1)主线程需要将文件描述符传递给函数线程;

          (2)函数线程启动起来后必须阻塞在获取文件描述符前;

          (3)信号量来控制主线程向函数线程通知获取文件描述符事件;

          (4)主线程在数组中插入数据以及函数线程获取数据都必须是互斥的。

             4、进程池实现难点

              进程池的实现难点是在主进程将获取到的客户连接文件描述符传递给进程池中的进程。这里用到进程间通讯的一些方式;

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux高性能服务器编程是一门专注于使用Linux操作系统和相关技术进行高效服务器开发的领域。在这个领域中,开发者需要充分利用Linux操作系统的特性和提供的各种工具,以确保服务器能够快速、稳定地处理大量并发请求。 以下是一些涉及到Linux高性能服务器编程的关键概念和技术: 1. 多进程/多线程编程Linux提供了多进程多线程编程模型,可以利用多核处理器的并行计算能力,并实现并发处理。开发者需要了解进程与线程的概念、创建和管理多进程/多线程的方法,以及进程间/线程间的通信与同步机制。 2. 异步IO编程:异步IO编程模型可以提高服务器的并发处理能力。Linux提供了epoll、kqueue等机制来实现高效的事件驱动编程,开发者可以利用这些机制实现非阻塞IO,处理大量的并发请求。 3. 网络编程服务器通常需要与客户端进行网络通信。Linux提供了socket编程接口,开发者可以使用TCP/IP或UDP协议进行网络通信。熟悉socket编程接口、网络协议和网络编程相关技术是进行高性能服务器开发的基础。 4. 内存管理:Linux提供了丰富的内存管理机制,包括内存映射、共享内存等。开发者需要了解内存管理的原理和使用方法,合理地管理服务器的内存资源。 5. 性能调优:为了达到高性能的要求,开发者需要对服务器进行性能调优。这包括对代码进行优化、减少系统调用的开销、合理配置系统参数等。 总之,Linux高性能服务器编程是一个广阔而复杂的领域,需要开发者具备扎实的编程基础和对Linux操作系统的深入理解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值