当前位置: 技术问答>linux和unix
关于Linux多进程与socket概念性问题与解决方案
来源: 互联网 发布时间:2015-12-27
本文导语: 小弟最近要编写一个服务器,和一个固定的客户端通信,该客户端是突发性发送数据,而且会一次发送很多数据。服务器采用的是fork多进程对客户端每一个特定数据进行处理,而不是来一个消息开一个进程。子进程...
小弟最近要编写一个服务器,和一个固定的客户端通信,该客户端是突发性发送数据,而且会一次发送很多数据。服务器采用的是fork多进程对客户端每一个特定数据进行处理,而不是来一个消息开一个进程。子进程在处理中需要和客户端进行通信。为了稳定,不考虑多线程。
问题如下:
1.以前我主进程accept之后,再fork,那么子进程相当于也执行了前面的连接过程,可以继续使用msssage_socket与客户端进程通信。但是现在我是先fork子进程,固定对某个类型信息进行处理,然后主进程才进行socket连接,我通过共享内存把msssage_socket给子进程,子进程却不能与客户端通信了,会报文件描述符错误。我想知道有没有简单的方法可以让子进程和客户端通信?
2.我想问下socket连接池这个概念,socket连接池保存的是什么?是socket获得的套接字(connect_socket)还是accept获得的msssage_socket?感觉从socket池取出一个连接就可以进行socket通信了,感觉悬悬的,连接的建立不是要针对特定客户端吗?像我如果只和一个客户端进行通信,是不是就可以?
3.
“主控制进程、连接处理进程、一组处理进程;其中主控制进程负责监控其他进程;连接处理进程首先是负责消息接入,接受消息,消息写入数据池,消息返回;处理进程是对数据迟中的数据进行处理,处理完成后将结果写入返回数据池,由接入进程返回给客户端,这个可以做成异步处理或者阻塞处理”
这个是前面某个帖子中回复的内容。我想问下,“主控制进程负责监控其他进程”是不是就是这个进程和其它进程进行通信,来转递数据?我的服务器好像把主控制进程和连接处理进程写在一个进程了,或者说我这样写那么子进程就不能和客户端通信了,应该是子进程如果要和客户端通信,那么就需要把要通信的数据发回给我的主进程,让主进程使用和客户端建立的socket通信,得到结果再发回给子进程。那么按照上面给的解决方案,就是主控制进程其实也不掌握socket连接,需要连接处理进程把内容发给主控制进程进行转发。不知道我的理解对不对?
综上所述:我的子进程想通过主进程建立的message_socket直接和客户端通信,没门。只能把要通信的数据再通过共享内存发回给主进程,让主进程和客户端通信,再把结果发回来给子进程。 如果想写的更好,更稳定,层次更清晰,就应该把我的主进程拆分为主控制进程、连接处理进程(这样比原来的方案每一个方面都好吗?)
是不是这样啊?外加一个socket池的问题。
有点啰唆了。
问题如下:
1.以前我主进程accept之后,再fork,那么子进程相当于也执行了前面的连接过程,可以继续使用msssage_socket与客户端进程通信。但是现在我是先fork子进程,固定对某个类型信息进行处理,然后主进程才进行socket连接,我通过共享内存把msssage_socket给子进程,子进程却不能与客户端通信了,会报文件描述符错误。我想知道有没有简单的方法可以让子进程和客户端通信?
2.我想问下socket连接池这个概念,socket连接池保存的是什么?是socket获得的套接字(connect_socket)还是accept获得的msssage_socket?感觉从socket池取出一个连接就可以进行socket通信了,感觉悬悬的,连接的建立不是要针对特定客户端吗?像我如果只和一个客户端进行通信,是不是就可以?
3.
“主控制进程、连接处理进程、一组处理进程;其中主控制进程负责监控其他进程;连接处理进程首先是负责消息接入,接受消息,消息写入数据池,消息返回;处理进程是对数据迟中的数据进行处理,处理完成后将结果写入返回数据池,由接入进程返回给客户端,这个可以做成异步处理或者阻塞处理”
这个是前面某个帖子中回复的内容。我想问下,“主控制进程负责监控其他进程”是不是就是这个进程和其它进程进行通信,来转递数据?我的服务器好像把主控制进程和连接处理进程写在一个进程了,或者说我这样写那么子进程就不能和客户端通信了,应该是子进程如果要和客户端通信,那么就需要把要通信的数据发回给我的主进程,让主进程使用和客户端建立的socket通信,得到结果再发回给子进程。那么按照上面给的解决方案,就是主控制进程其实也不掌握socket连接,需要连接处理进程把内容发给主控制进程进行转发。不知道我的理解对不对?
综上所述:我的子进程想通过主进程建立的message_socket直接和客户端通信,没门。只能把要通信的数据再通过共享内存发回给主进程,让主进程和客户端通信,再把结果发回来给子进程。 如果想写的更好,更稳定,层次更清晰,就应该把我的主进程拆分为主控制进程、连接处理进程(这样比原来的方案每一个方面都好吗?)
是不是这样啊?外加一个socket池的问题。
有点啰唆了。
|
你可以直接对socket的描述符进行操作,linux里面就是文件的概念。
比如如果你的socket描述符是22,那你write/read 22都可以收发数据。
但是你建两个同样的socket是不可以的。
似乎上面说的对你的三个问题都有用。
由于你是1--1的情况,建议你
共享内存
接收进程------消息环----分拣进程---处理进程(n)
比如如果你的socket描述符是22,那你write/read 22都可以收发数据。
但是你建两个同样的socket是不可以的。
似乎上面说的对你的三个问题都有用。
由于你是1--1的情况,建议你
共享内存
接收进程------消息环----分拣进程---处理进程(n)
|
猪头怎么也跑这来了?
打声招呼先:)
==================================
我不知道LZ的需要是什么,理解能力有点差,也懒得去想
以前我作过这么一个设计:
把accept的socket 放到一个队列中,包括一些辅助信息了,然后会对这些socket进行轮询,如果有数据接收、解析,根据解析结果放到相应的管道,而每个管道各自有一个进程在负责处理这些消息。再建立一个发送的管道,所有需要发送的数据(包括辅助信息,不然不知道用哪个socket来发送)都放入这个管道中,刚才的接收进程在接收之前或者之后,处理这个发送队列。
这么设计是因为我的处理过程比较烦琐,而且处理过程返回也不是同步的,而数据量不是很大的情况。如果你数据量非常大,那么这个就不适合你了,也许你需要的是给每个连接产生一个线程,或者使用线程池
打声招呼先:)
==================================
我不知道LZ的需要是什么,理解能力有点差,也懒得去想
以前我作过这么一个设计:
把accept的socket 放到一个队列中,包括一些辅助信息了,然后会对这些socket进行轮询,如果有数据接收、解析,根据解析结果放到相应的管道,而每个管道各自有一个进程在负责处理这些消息。再建立一个发送的管道,所有需要发送的数据(包括辅助信息,不然不知道用哪个socket来发送)都放入这个管道中,刚才的接收进程在接收之前或者之后,处理这个发送队列。
这么设计是因为我的处理过程比较烦琐,而且处理过程返回也不是同步的,而数据量不是很大的情况。如果你数据量非常大,那么这个就不适合你了,也许你需要的是给每个连接产生一个线程,或者使用线程池
|
为了稳定,不考虑多线程。
对于楼主这句话表示怀疑
如果设计得当,线程一样很稳定,而且性能绝对比多进程要好得多
对于楼主这句话表示怀疑
如果设计得当,线程一样很稳定,而且性能绝对比多进程要好得多
|
1、参考 APUE 和 UNP 都有的,用 AF_LOCAL socket 传递文件描述符的方法。
至于架构设计的问题,需要具体分析性能和要求。。
至于架构设计的问题,需要具体分析性能和要求。。
|
没看明白,首先你和客户端有几个socket连接,是多个连接,还是就一个连接。是短连接,还是长连接。
看楼主的意思,应该是一个连接,好像还是长连接吧!
不过,没看明白的是,你的recv在哪?是在主进程还是子进程。
如果是在父进程中,recv/send是在一个进程中,那么就不用fork多个子进程了呀!
看楼主的意思,应该是一个连接,好像还是长连接吧!
不过,没看明白的是,你的recv在哪?是在主进程还是子进程。
如果是在父进程中,recv/send是在一个进程中,那么就不用fork多个子进程了呀!
|
linux下的线程不是很高效,根本不能和windows下的线程等同起来。
给你个网址,自己看看吧
http://zhoulifa.bokee.com/5378803.html
给你个网址,自己看看吧
http://zhoulifa.bokee.com/5378803.html
|
多个进程之间的fd定义是不一样的,你先fork,主进程先accept再把sock_fd这个整数传给另一个进程,另一个进程根本就没有这个fd,所以是非法的fd.
你这种情况下,既然想prefork一组进程,最简单的是每个子进程直接accept(),accept一个连接之后,完整的处理一个连接直到关闭就可以了。
你这种情况下,既然想prefork一组进程,最简单的是每个子进程直接accept(),accept一个连接之后,完整的处理一个连接直到关闭就可以了。
|
如果你的client会比较多,也就是同时的并发连接可能很多的时候,可能这样做的情况下,新的连接可能很久都没有人accept,建议使用epoll或者select模型,主进程负责所有的网络操作。
收到的数据通过SHM转给一组子进程来处理。
收到的数据通过SHM转给一组子进程来处理。