当前位置: 技术问答>linux和unix
多任务的并发通讯与控制问题
来源: 互联网 发布时间:2016-05-03
本文导语: 当前要设计一个任务分配并发系统。 设计思路如下: 主进程1 子进程若干 -> 中间件 主进程从数据库中查询到待处理任务,向子进程分配,子进程调用中间件完成任务处理。 主进程与子进程通过文件进行...
当前要设计一个任务分配并发系统。
设计思路如下:
主进程1 子进程若干 -> 中间件
主进程从数据库中查询到待处理任务,向子进程分配,子进程调用中间件完成任务处理。
主进程与子进程通过文件进行通讯。
主进程负责将任务分配情况写入文件,子进程读取文件,找到属于自己的任务调用服务完成处理。此处子进程对任务文件只读。
这样设计有个问题,因为主进程轮询任务的时间频率m1与子进程轮询任务文件的时间间隔c1是不一致的。m1要大于c1.这样就会出现在m1时间内,子进程可能多次读到相同的任务文件,继而对相同的任务进行多次调用,当然在第一次调用的时候任务就已经完成了,之后的相同调用都会无谓的调用服务。
曾考虑子进程也对任务文件进行写操作,完成任务后回写文件处理,但这样处理担心会与主进程的文件写操作产生冲突,限制子进程并发量不可太大,也就失去了并发的意义。
如何进行并发控制才好呢??请专家指点一二。:)
设计思路如下:
主进程1 子进程若干 -> 中间件
主进程从数据库中查询到待处理任务,向子进程分配,子进程调用中间件完成任务处理。
主进程与子进程通过文件进行通讯。
主进程负责将任务分配情况写入文件,子进程读取文件,找到属于自己的任务调用服务完成处理。此处子进程对任务文件只读。
这样设计有个问题,因为主进程轮询任务的时间频率m1与子进程轮询任务文件的时间间隔c1是不一致的。m1要大于c1.这样就会出现在m1时间内,子进程可能多次读到相同的任务文件,继而对相同的任务进行多次调用,当然在第一次调用的时候任务就已经完成了,之后的相同调用都会无谓的调用服务。
曾考虑子进程也对任务文件进行写操作,完成任务后回写文件处理,但这样处理担心会与主进程的文件写操作产生冲突,限制子进程并发量不可太大,也就失去了并发的意义。
如何进行并发控制才好呢??请专家指点一二。:)
|
有两种方法比较好处理
1.主进程读到任务后fork出子进程处理,只要子进程处理时间超过1s的都可用
2.用system v消息队列,主进程往消息队列里写数据,并定义type,就可让子进程读到自己的任务
其他的unix域估计也行,不过效率要低点;管道不推荐用,容易出现数据偏差,很难从中恢复,如果一定要用
文件就用文件锁来处理并发
1.主进程读到任务后fork出子进程处理,只要子进程处理时间超过1s的都可用
2.用system v消息队列,主进程往消息队列里写数据,并定义type,就可让子进程读到自己的任务
其他的unix域估计也行,不过效率要低点;管道不推荐用,容易出现数据偏差,很难从中恢复,如果一定要用
文件就用文件锁来处理并发
|
如guosha所言,我多说两句:
如果你的子进程只是处理文件里面的任务,没有其它附带任务要做,那么用guosha所得信号量,主进程post,子进程wait,就可以很很好解决你的问题了! 如果子进程还有附带任务,那么子进程wait的话有可能会阻塞附带任务的处理。这样的话,你也许可以考虑用管道或者本地socket,然后在子进程中采用select(设定超时)来等待主进程的消息。由于设定了超时,即使没有收到消息,子进程也会由于超时而继续执行,不会阻塞(从而附带的任务也有机会执行)。
good luck!
如果你的子进程只是处理文件里面的任务,没有其它附带任务要做,那么用guosha所得信号量,主进程post,子进程wait,就可以很很好解决你的问题了! 如果子进程还有附带任务,那么子进程wait的话有可能会阻塞附带任务的处理。这样的话,你也许可以考虑用管道或者本地socket,然后在子进程中采用select(设定超时)来等待主进程的消息。由于设定了超时,即使没有收到消息,子进程也会由于超时而继续执行,不会阻塞(从而附带的任务也有机会执行)。
good luck!
|
这种事情用消息队列多好?
如果任务不是太多, 太频繁, 而且坚持要用文件,可以考虑用目录, 特定子进程的任务存指定的目录, 一个任务一个文件, 这样任务执行完删点文件即可, 但读写文件时同样要加锁。
如果任务不是太多, 太频繁, 而且坚持要用文件,可以考虑用目录, 特定子进程的任务存指定的目录, 一个任务一个文件, 这样任务执行完删点文件即可, 但读写文件时同样要加锁。
|
为嘛要用文件来分配任务?管道或消息队列都要比你的方案简单且可靠,还不用显式进程同步,子进程也不需要轮询