对多线程网络编程的理解
本文主要涉及,线程的构建,线程之间的通信以及网络源端和目的端的通信接口的操作这三个问题。
一、线程的创建
对于线程的创建,首先要明确使用线程的目的,使用线程给我们的程序能够带来什么好处。结合我的经验,我认为使用线程的好处主要有:
1.线程是一个独立运行的个体,它可以独立完成我们交给它的任务,而不需要我们在程序中主动显式调用;
2.当程序处理的问题及逻辑庞大时,显然,线程可以降低主线程的复杂性,使程序逻辑较为清楚;同时,方便我们进行调试,根据线程ID,迅速找到问题;
3.对于现今多核CPU的发展,多个线程可以实现真正意义上的同时运行,这显然可以明显提高程序的运行效率和数据的处理效率(对于涉及到大量并行数据处理的程序而言)。
当然,以上三点的建立基础都来源于线程的良好设计与线程之间的良好分工,否则一切都免谈。因此,问题就转化为了我们如何来设计线程。我认为,设计定义线程的时候需要
考虑,线程所要完成的主要功能是什么,线程处理的数据有哪些,这并不是一件简单的事。进一步地,在编程的时候,我们必须要考虑数据的流向,数据的流向是由其实现的功
能所决定的,线程主要的数据来自哪里,是来自网络对端,还是来自本地。如果是来自网络对端,那么就必须明确通信接口,如常用的socket接口;如果是来自本地,那么数据
存放的空间在哪,该空间是否有我们要处理的数据,数据到来的检测一般有中断触发和周期性探测两种方式。周期性检测相对较为简单一些,可以设立一个定时器,在定时器超
时时调用数据检测函数去判断,进而触发相应的信号。线程捕捉该信号,进入数据处理流程。当然,必须明确的一点是定时器的实现也是一个独立的线程。
在明确了数据源之后,我们便可以设计数据处理过程了。这个时候,要考虑的是,数据的处理逻辑,数据的作用域,该数据最终存储的空间等问题。处理逻辑可以按照功能设计
一系列的处理函数,针对不同的情形显式调用就可以。数据的作用域包括数据的类型,static或是extern,是否是const类型,数据声明的位置是在哪个具体的函数,这个函数在
哪里结束等。
数据的存储就是数据的去向,是存储在内存中,数据库中,还是某个文件中,对于不同的存储去向,其相应的访问权限是什么?别的线程是否可以访问,是否可以修改,访问的
时候是否需要添加信号量保护包括或是上锁保护。
最后,当线程进行完此轮数据处理之后,线程的进一步状态是什么,是退出,还是阻塞在某个信号上,或是某个结束标志上,如isStop=0或是1,通过改变这个变量,进而决定
线程的生存状态。
二、线程之间的通信
线程之间的通信一直是一个比较困难的问题,《unix网络编程卷2》也对进程间通信方式做了很多的讲解,一般主要有FIFO,socket,共享内存,消息队列,信号量等方式,对于这
块内容,我也一直在学习的过程中,linux中非常好用的重定向工具就是FIFO思想的最好体现,socket可以实现源端和目的端的通信,源和目的不一定在两台主机上,在一台主
机上只要四元组信息(源IP地址,源端口,目的IP地址,目的端口)不完成相同即可,消息队列还没有使用过,共享内存个人理解的一种简单实现方式创建全局变量,不同线程通
过互斥量访问修改这个全局变量,进而实现线程同步。信号量的使用和互斥量类似。
三、网络源端和目的端的通信接口的操作
对于这一点,我个人的体会是,在编程前就像拿着手机打电话一样,每个手机就代表一个通信接口,想清楚程序是和谁要进行通信的,对端的手机号是多少,我要和多少人进行
通信,是否需要不同的手机去通信,在程序中,就是定义UdpSocket或是TcpSocket的问题,一个手机就是一个socket的,手机号就是IP地址+端口号,当想清楚这个问题之
后,就可以通过不同的通信接口来拿到数据了。
这只是我在学习单服务器多客户端模式下编程时的一点思考,欢迎大家批评指正!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。