免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: woodie
打印 上一主题 下一主题

[shell应用进阶]:限制同时运行脚本实例的个数 -- 串行化:换一个思路。  关闭 [复制链接]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
21 [报告]
发表于 2006-10-12 14:52 |只看该作者
原帖由 網中人 于 2006-10-12 13:15 发表
呵. woodie 兄的 idea 不錯!
不過, 從 ethernet 的原理來看, 倒不像是 token ring, 反而像是 CSMA/CA .
也就是 request to send(RTS) 跟 clear to send(CTS) .

還是我理解錯了?

我的意思是每个进程取得令牌后才运行关键代码段,这一点上与令牌环的得到令牌后才能发送数据的情况比较类似。
当然每个进程请求令牌的过程存在相互的竞争,这在一定程度上又有些类似以太网的竞争环境。网兄说的也没错。着眼点不同罢了。^_^
相反的,Token Ring的令牌好像是在环路上自动轮转的,“皇帝轮流做,明年到我家”,不存在竞争的过程。

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
22 [报告]
发表于 2006-10-12 15:15 |只看该作者
pid=`sed -n '/stop/ {s/\([0-9]\+\) \+stop/\1/p;q}' /tmp/p-aquire`

这一点似乎还是有问题,会有stop被抛弃掉而没有收回number_of_running么?

论坛徽章:
7
荣誉版主
日期:2011-11-23 16:44:17子鼠
日期:2014-07-24 15:38:07狮子座
日期:2014-07-24 11:00:54巨蟹座
日期:2014-07-21 19:03:10双子座
日期:2014-05-22 12:00:09卯兔
日期:2014-05-08 19:43:17卯兔
日期:2014-08-22 13:39:09
23 [报告]
发表于 2006-10-12 15:39 |只看该作者
原帖由 waker 于 2006-10-12 15:15 发表
pid=`sed -n '/stop/ {s/\([0-9]\+\) \+stop/\1/p;q}' /tmp/p-aquire`

这一点似乎还是有问题,会有stop被抛弃掉而没有收回number_of_running么?

这样有可能丢令牌,当管道中有多于一个的stop消息时。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
24 [报告]
发表于 2006-10-12 15:56 |只看该作者
原帖由 r2007 于 2006-10-12 15:39 发表

这样有可能丢令牌,当管道中有多于一个的stop消息时。

会吗?一行不会有多个stop,匹配到第一个stop并处理后sed就用q命令退出了呀。然后收回令牌,运行数量减一,进入下一循环并读取下一行。会丢失stop行吗?

论坛徽章:
7
荣誉版主
日期:2011-11-23 16:44:17子鼠
日期:2014-07-24 15:38:07狮子座
日期:2014-07-24 11:00:54巨蟹座
日期:2014-07-21 19:03:10双子座
日期:2014-05-22 12:00:09卯兔
日期:2014-05-08 19:43:17卯兔
日期:2014-08-22 13:39:09
25 [报告]
发表于 2006-10-12 16:24 |只看该作者
原帖由 woodie 于 2006-10-12 15:56 发表

会吗?一行不会有多个stop,匹配到第一个stop并处理后sed就用q命令退出了呀。然后收回令牌,运行数量减一,进入下一循环并读取下一行。会丢失stop行吗?

不会

有个简单的方法不知道如何
事先建一个管道,比如 /dev/my-script.token
然后在启动脚本中向其中灌入若干空行,需要并行几个就写几个。
在用户脚本中,先尝试从管道中取一行,如成功则继续运行,否则继续等待,完成后向管道送回一个空行。
大体意思如下可参考这里---能不能用shell做一个队列)
while (1) {
读管道(可以设定一个timeout值)
如果$?=0, 跳出循环继续用户代码
否则继续循环(可加一个计数,如果超出,则exit $errno)
}

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
26 [报告]
发表于 2006-10-12 16:56 |只看该作者
To r2007:
嗯,不错的想法!一直等待的话并不可取,加上timeout的话就完全可行了。
不过进程意外退出的情况应该如何处理呢?似乎可以由每个运行的进程将进程号写入一个文件,再由管理端来检测是否在运行。跟楼顶的做法正好相反,由进程端生成运行进程列表文件,管理端要做的事情就比较少了。如果不检测失效令牌的话,管理端就完全可以省略!如果在每个进程内部检测失效的话,又会出现竞态的问题,所以最好还是管理端来做。
很有启发性,谢谢!

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
27 [报告]
发表于 2006-10-12 17:28 |只看该作者
七兄,好像不行啊!首先我机器上的测试显示:read -t只在bash, ksh93, zsh下合法,linux下的bsh,和pdksh不能用。
而且在能用的平台上似乎超时时间结束后并不退出,而是挂在那里不动了。
bash man page上说:
...
This option has no effect if read is not reading input from the terminal or a pipe.
...
难道这里的pipe不包括fifo?不解...

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
28 [报告]
发表于 2006-10-12 17:30 |只看该作者
难道只好自己编码来处理超时?不甘心。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
29 [报告]
发表于 2006-10-12 17:39 |只看该作者
好像是用-t选项读fifo无效,测试过了普通的管道正常。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
30 [报告]
发表于 2006-10-12 17:51 |只看该作者
掉到read -t的陷阱里去了!其实有更简单的方法:就是用普通的文件而不用fifo,令牌用append附加到该文件,然后直接读取,不用加超时,read命令会直接返回,然后检查返回状态就可以了。^_^

----------------------------------------------------------------------------------
等等,又发现问题,用普通文件的话读到一行后应该删除一行,否则不能体现一个进程已经领取令牌的事实,但删行......又掉进了竞态的老泥坑里了,晕菜!还是用fifo吧。
那通过真正的管道转发fifo的内容呢?
head -1 /tmp/p-aquire | read -t 3 V
也不行!这回挂在那里的倒不是read,而是head了,read在一边陪绑!
用其它语言写一个会超时的工具去读fifo?但那兼容性岂不是越发地差了吗?
不用fifo,通过socket实现如何?还是算了,编程用到的工具又降低了兼容性。
看来只能用shell自己来处理。但会可能用到子shell,变量不能直接回传...如何检测read的返回状态?用exit?
越来越麻烦了。
七兄有什么简单的好办法教我吗?

[ 本帖最后由 woodie 于 2006-10-12 18:56 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP