- 24
- 0
我有如下脚本upgrade.sh,前端页面通过php调用,但多个页面间可以同时调用,比如升级时php端先执行--download,在download前都可以取消,download完成后,然后再调用install_pkg(在install_pkg时不可取消),现在download下来的包如何存放才能避免并发逻辑?
我现在是php端调用了./upgrade.sh --download之后,我将下载的pkg包路径(包含文件名)写入到固定文件中,下载的包存放在随机目录中,然后php再调用./upgrade.sh --install去安装。安装的时候我执行--install去获取我们保存pkg路径信息,然后去安装。
之所以需要调用两次脚本,分开是因为要支持取消升级。如果写在一个流程里无法实现取消升级的操作。
由于php要调用两次,所以也不能用单例模式,如果只需要调一次,那么就可以通过单例实现同时只调用一次。被这个问题折磨一天,写得乱七八糟,希望各位能给点意见。
function main()
{
if [ "$1" == "--download" ]; then
download_pkg
elif [ "$1" == "--install" ]; then
install_pkg
else
usage
fi
}
main $@ - 共 0 条
- 全部回答
-
麽麽茶 普通会员 1楼
在Shell中解决竞争问题通常涉及到进程同步和资源的管理。以下是一个简单的示例,展示如何在多个进程之间共享一个文件资源,同时防止其中一个进程试图修改另一个进程已经读取的文件内容:
```bash
!/bin/bash
获取文件路径和文件名
file_path="$1" file_name="$2"
初始化文件和进程列表
files=() processes=()
遍历目录下所有可读文件
for file in "$file_path"/*.txt; do # 如果文件不存在或为文本文件,则忽略 if [ ! -f "$file" ] || [ ! -i "$file" ]; then continue fi
# 判断文件是否已读取 if [ ! -r "$file" ]; then # 添加文件到进程列表 files+=("$file") fi # 创建进程并启动 p=$(pidof $file) p+=1 p=($p%${processes[@]}+1) pids+=($p) # 检查是否有其他进程正在修改同一文件 for process in "${processes[@]}"; do if [ -z "$process" ]; then # 启动进程 p=$(pidof $file) p+=1 p=($p%${processes[@]}+1) pids+=($p) process=$p break fi # 判断文件是否已读取 if [ ! -r "$file" ]; then # 如果正在读取,阻止其修改文件 # 可以使用umask(文件权限)来限制其他进程读取权限 [ $p -o $process`umask 022` -o $process`umask 011` -o $process`umask 010` ] &> /dev/null fi done # 在每个进程结束时,清除进程列表和进程 ID for pid in "${pids[@]}"; do pids[$pid]=0 pids[$pid]=0 donedone
检查是否有其他进程正在修改同一文件
for process in "${processes[@]}"; do if [ -z "$process" ]; then # 启动进程 p=$(pidof $file) p+=1 p=($p%${processes[@]}+1) pids+=($p) process=$p break fi
# 检查文件是否已读取 if [ ! -r "$file" ]; then # 如果正在读取,阻止其修改文件 # 可以使用umask(文件权限)来限制其他进程读取权限 [ $p -o $process`umask 022` -o $process`umask 011` -o $process`umask 010` ] &> /dev/null fidone
删除进程
for pid in "${pids[@]}"; do pids[$pid]=0 done
删除进程列表
for pid in "${pids[@]}"; do pids[$pid]=0 done ```
在这个示例中,我们首先获取了要共享的文件路径和文件名。然后,我们创建了一个包含所有要处理的文件的列表,以及一个包含所有正在处理文件的进程列表。我们遍历文件目录下的所有可读文件,并检查它们是否已读取。如果文件尚未读取,我们将文件添加到进程列表中。然后,我们创建并启动每个进程,检查它是否正在读取文件,并在进程结束时,检查文件是否已读取,阻止它修改文件。如果文件正在读取,我们可以使用umask来限制其他进程读取权限,从而防止其他进程修改文件内容。最后,我们删除了处理过的文件列表和进程列表,以确保所有的资源都被正确地释放。
注意,这只是一个基本示例,实际应用中可能需要根据具体的需求和环境来调整,例如使用更复杂的同步机制(如信号量、互斥锁等),处理更复杂的文件格式(如二进制文件、二进制序列文件等),以及在进程启动和结束时更精确地检查文件状态等。
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部

