标题: [文件操作] [已解决]求助:同一bat复用避免冲突问题 [打印本页]
作者: hlzj88 时间: 2023-9-25 20:25 标题: [已解决]求助:同一bat复用避免冲突问题
本帖最后由 hlzj88 于 2023-9-28 21:46 编辑
- @echo off
- :ks
- copy /y 1.html 2.html
- if exist ..\标志2.ini goto ks
- if exist ..\标志3.ini goto ks
- echo,>>..\标志1.ini
- htox32c /IP /O0 /U1+4 2.html
- del /q 2.html
- del /q ..\标志1.ini
- echo 其他语句
- if exist *.html goto ks
复制代码
要复用的代码构造框架思路如上,因为效率问题计划把该bat复制到三个文件夹(wjj1 wjj2 wjj3)下,由另外bat分配文件并都(或者手动)启动他们加快处理文件。因hto32c不允许同时运行,会有同时运行的情况出现,导致暂停,结果出错现象。
由此,想令 在(wjj1 wjj2 wjj3)不同文件夹下运行运行时,产生可以彼此区分的标志,当其中一个运行到启动hto32c前,现检测上级文件夹是否有其他标志来暂缓自己启动hto32c时间,直到没有标志存在,自己就继续运行。
因为bat较大,不想同时保存三个。所以,求助,同一bat,运行时如何产生一个独有标志,并能被另外运行的同一源码的bat检测到。同时运行三个,应当有3个可以互相检测的标志。
另,假设 wjj1 下文件处理完毕停止运行,又添加进新html再次启动,产生的标志依据能被另外两个识别到。
自己思考了几个方案,都不能避免冲突现象,特此求助论坛大佬,希望能给出解决方法。
假如采用上面代码测试,容易因1.html是固定大小的,因此彼此运行间隔也统一。会虚假的不会冲突。
原始问题是这样,谢谢大家,
作者: czjt1234 时间: 2023-9-25 20:44
- @echo off 2>con 3>&2 4>>%0
- echo single instance batch
- echo http://demon.tw
- pause
复制代码
不知道这个你适用不
防止批处理重复运行
作者: hlzj88 时间: 2023-9-25 21:03
回复 2# czjt1234
谢谢。代码不能达到效果。。需要的是bat可以运行,但内含的exe启动要互相避让。
作者: Batcher 时间: 2023-9-25 21:57
回复 1# hlzj88 - :WaitLock
- if exist "..\file.lock" (
- echo Wait ..\file.lock to be deleted
- timeout /t 1 /nobreak >nul
- goto :WaitLock
- )
- type nul >"..\file.lock"
- htox32c /IP /O0 /U1+4 2.html
- del /f /q "..\file.lock"
复制代码
作者: hlzj88 时间: 2023-9-25 22:22
回复 4# Batcher
坛主意思是复用几个都只检测同一个文件。
想了想,也许这是最佳办法。反而变不复杂了。
作者: hlzj88 时间: 2023-9-26 19:52
经加入试运行,还是会出现冲突现象。也许瞬间两个同时启动,在毫秒之间。无法避免。
结帖
作者: 77七 时间: 2023-9-26 21:44
- @echo off
- :loop
- set str=%random%%random%%random%
- if exist "htox32c.exe" (
- ren "htox32c.exe" "htox32c%str%.exe" 2>nul
- )
- if exist "htox32c%str%.exe" (
- "htox32c%str%.exe" /IP /O0 /U1+4 2.html
- ) else (
- timeout 1 >nul
- goto :loop
- )
- ren "htox32c%str%.exe" "htox32c.exe"
复制代码
把exe改个名字,这样可以吗
作者: Batcher 时间: 2023-9-26 21:50
回复 6# hlzj88
循环内部生成一个1到5之间的随机数,执行exe之前随机延时1~5秒。
作者: hlzj88 时间: 2023-9-26 22:01
谢谢 7楼 8楼,我都再试试看。
作者: hlzj88 时间: 2023-9-27 00:39
用500+html 分别放入1 2 3 三个文件夹内,用for 语句启动他们,
回复 7楼 1 set str=%random%%random%%random%在loop内,导致处理没有txt产生,放外面能出现txt 。 2 三个文件夹里exe都命名为同一随机尾数exe,太晚,明天再修改试看看结果
回复 8楼 没有处理完,已经出现几次exe同时运行的错误。
作者: 77七 时间: 2023-9-27 02:39
回复 10# hlzj88
exe只用一个,只有重命名成功的那个bat会执行操作,操作后会改回原名。然后循环下去。
set 随机数是疏忽了,以前听大佬说,大概是相同时间(可能以秒算),确实会产生相同的随机数,
那就放loop外面,打开bat时间隔1秒,确保3次的随机数不同。
- @echo off
- set str=%random%%random%%random%
- :loop
- if exist "d:\htox32c.exe" (
- ren "d:\htox32c.exe" "htox32c%str%.exe" 2>nul
- )
- if exist "d:\htox32c%str%.exe" (
- "d:\htox32c%str%.exe" /IP /O0 /U1+4 2.html
- ) else (
- timeout 1 >nul
- goto :loop
- )
- ren "d:\htox32c%str%.exe" "htox32c.exe"
复制代码
或者用一个bat带参数执行自身。
- @echo off
- %1 (for %%a in (1 2 3) do (start "" "%~f0" rem %%a))&exit
-
- if "%~2" equ "1" (
- pushd "d:\test1"
- ) else if "%~2" equ "2" (
- pushd "d:\test2"
- ) else if "%~2" equ "3" (
- pushd "d:\test3"
- ) else goto:eof
-
- set str=%~2
-
- :loop
- if exist "d:\htox32c.exe" (
- ren "d:\htox32c.exe" "htox32c%str%.exe" 2>nul
- )
- if exist "d:\htox32c%str%.exe" (
- "d:\htox32c%str%.exe" /IP /O0 /U1+4 2.html
- ) else (
- timeout 1 >nul
- goto :loop
- )
- ren "d:\htox32c%str%.exe" "htox32c.exe"
复制代码
作者: aloha20200628 时间: 2023-9-27 11:56
通读了n遍一楼的大段'密文',未能破解其原意。
个人理解似乎是lz有一堆网页文件*.html,分置在三个目录中,要用一个网页转文本工具HtoX32c.exe,设法高效处理这三个目录...
本人所知的批处理脚本解决之道,有并发进程即并联方案,如
start "" /b HtoX32c.exe ... d:\wjj1\*.html
start "" /b HtoX32c.exe ... d:\wjj2\*.html
start "" /b HtoX32c.exe ... d:\wjj3\*.html
如果并联方案不通,即HtoX32c.exe不能在并发进程中被同时运行,也许就只能采用通常的串行方案,如
HtoX32c.exe ... d:\wjj1\*.html
HtoX32c.exe ... d:\wjj2\*.html
HtoX32c.exe ... d:\wjj3\*.html
除以上二者之外,看来lz是要探讨第三条路可否用批处理脚本提速...
关注此帖不断升高。
作者: czjt1234 时间: 2023-9-27 15:37
计划把该bat复制到三个文件夹(wjj1 wjj2 wjj3)下
那是否可以新建个文本文档,把 wjj1 wjj2 wjj3 写进去,一行一个
然后批处理依次处理每行的文件夹名
作者: Five66 时间: 2023-9-27 19:12
新增一个bat.用于管理标志文件,不知行否
比如- @echo off
- set b=1
- set "ph=d:\a"
-
- :s
- cd.>"%ph%\标志1.ini"
- call set a=%%b%%
- del "%ph%\标志1.ini" 2>nul
-
- cd.>"%ph%\标志2.ini"
- call set a=%%b%%
- del "%ph%\标志2.ini" 2>nul
-
- cd.>"%ph%\标志3.ini"
- call set a=%%b%%
- del "%ph%\标志3.ini" 2>nul
-
- goto :s
复制代码
作者: hlzj88 时间: 2023-9-27 19:28
本帖最后由 hlzj88 于 2023-9-27 19:37 编辑
回复 12# aloha20200628
我做了个结构化的网络小说整理为本地单网页工具,各个单独功能为一个bat部件。按流程调用。由此,单功能部件可为其他所调用,也可独立运行。也方便单独修改。
原来流程为只要开始下载网页就在一个文件夹内开始处理网页,因处理为文本的bat同时含有标点转换,非正常文字踢出,字符转换,段落重排版等功能,所以耗时较多,处理就慢。通常下载完还需要等很久文本。
以前也就速度有过优化,以我只略懂bat的能力感觉已无力再提速。也是最近才想进行并行处理。两个并行出错少,但依旧需要等待。三个并行速度才约等于下载速度。hto32c不能并行运行,会出现卡住需人工干预现象,才想办法令他不能同时运行。
大意如上。因此不能依次启动bat,bat已设计为自循环。只可在避免同时运行hto32c上下功夫。或者你们有更好合理的方案。
作者: hlzj88 时间: 2023-9-27 19:50
回复 14# Five66
怪我描述不彻底。实际情况是一个bat里必须用一次hto32c,还有一次满足条件也用一次的情况。 况且bat是自循环,如果三个bat在一个文件夹内抢文件,产生临时文件,删除临时文件,可能会更乱。所以是安排三个文件夹让他们彼此不乱。
作者: hlzj88 时间: 2023-9-27 20:24
本帖最后由 hlzj88 于 2023-9-27 20:39 编辑
回复 11# 77七
三个文件夹,已预先改名hto32c.exe,令他们不同,测试bat内已不含随机数,反复改名语句,只强行转换html。结果冲突。
看来并非改名可以避免,而是在hto32c工作内部会冲突。
作者: 77七 时间: 2023-9-27 20:45
回复 17# hlzj88
我觉得你没理解代码的意思,只用一个 exe,三个bat 全对这一个 exe 进行改名,即使三个bat同时改名,也应该只会成功一个吧,或者都不成功?反正不会存在,改名后多出一个exe 的情况。然后改名成功的,会执行操作,操作完毕改回原名,其它bat判断到存在原名的exe又会改名,这个我觉得100%不会存在两个exe同时操作的情况。
作者: hlzj88 时间: 2023-9-27 21:35
回复 18# 77七
谢谢,才理解你的意思。这样的确是有道理。我稍后试试。
作者: aloha20200628 时间: 2023-9-27 22:01
n个批处理脚本都在运行,其都要调用的abc.exe又不能被并行或重叠运行(无论abc.exe被更名与否) — 那么稳妥可靠的解决方案就是如何动态规划abc.exe的顺序运行,但遗憾的是,简单的批处理脚本没有多个并行进程之间的"隔离保护"或"相互防干扰"功能,故只能被允许静态顺序运行abc.exe,例如每个批处理脚本中在abc.exe之前的流程A可用并行方法提速,直到各个脚本中的A流程全部完成,再顺序运行n次abc.exe,然后各个批处理脚本的后续流程再用并行方法提速完成。
如果不能用 start "" /b abc.exe ... 并发多个abc.exe进程(无论abc.exe被更名与否),也就很难用并行方法(无论何种途径)可靠运行多个包含abc.exe的批处理脚本,除非有精确模型能预算出每个脚本中abc.exe本身和之前流程的时耗以便动态规划。
我本人经历 '下载网页以及清洗网页' 的路径,是最终转向了Python。
作者: Five66 时间: 2023-9-28 02:35
回复 16# hlzj88
是说用新的bat来专门管理.不是让各自的bat来
管理bat- @echo off
- set b=1
- set "ph1=wjj1"
- set "ph2=wjj2"
- set "ph3=wjj3"
- start "%ph1%\aaa.bat"
- start "%ph2%\aaa.bat"
- start "%ph3%\aaa.bat"
- :a
- cd.>"%ph1%\标志.ini"
- call set a=%%b%%
- goto :b
- :b
- if exist "%ph1%\标志.ini" goto :b
- cd.>"%ph2%\标志.ini"
- call set a=%%b%%
- goto :c
- :c
- if exist "%ph2%\标志.ini" goto :c
- cd.>"%ph3%\标志.ini"
- call set a=%%b%%
- goto :d
- :d
- call set a=%%b%%
- if exist "%ph3%\标志.ini" goto :d
- goto :a
复制代码
aaa.bat- @echo off
- :ks
- copy /y 1.html 2.html
- if not exist ..\标志.ini goto ks
- htox32c /IP /O0 /U1+4 2.html
- del /q 2.html
- del /q ..\标志.ini
- echo 其他语句
- if exist *.html goto ks
复制代码
作者: 老刘1号 时间: 2023-9-28 10:40
本帖最后由 老刘1号 于 2023-9-28 11:24 编辑
回复 4# Batcher
完全错误的锁实现
多个线程都有同时执行到第七行的可能
并发问题,无非上锁或者生产者消费者统一调度
作者: 老刘1号 时间: 2023-9-28 10:51
本帖最后由 老刘1号 于 2023-9-28 10:54 编辑
回复 20# aloha20200628
计算机世界中不要轻易说 “不能”
否则只会暴露自己的无知
进程之间本身就是独立的,文件的独立也可以通过文件名最后附加不同的随机数实现
共享资源还需要预测时间?真是滑天下之大稽
但凡系统学过一点并发编程都说不出这话
这东西和语言也没有直接关系,py的多线程支持也是一坨*
甚至语言层面都是跑在一个核上的,最近的标准才准备扔掉这个特性
作者: 老刘1号 时间: 2023-9-28 11:30
楼主可以考虑去搜一下多线程的 peterson 算法实现
作者: aloha20200628 时间: 2023-9-28 11:53
回复 23# 老刘1号
我们所指的‘能与不能’是源于Lz提出的 hto32c.exe 不能同时运行,诸位参与探讨交流都是基于这个‘不能’的主线。你对此有‘能’的解决方案,请予分享。
其实,编码就是在诸多‘能否’ ‘是否’之间取舍,不可含糊,否则编码就无从下手,而相关的讨论交流也没法明确而有效。
说到python,并非是用python重蹈纯P之覆辙,而是凭借其丰富的资源和现成工具大有捷径可行...
作者: czjt1234 时间: 2023-9-28 12:04
不知道楼主为什么不考虑我的意见,非要解决进程并发问题
我的意思是,从解决问题的角度出发,把进程并发改为htm文件并发- @echo off
- set wj1=wj1
- set wj2=wj2
- set wj3=wj3
- :loop
- for /f "delims=" %%i in ('dir /b %wj1%\*.htm') do (
- htox32c.exe %%i
- )
- for /f "delims=" %%i in ('dir /b %wj2%\*.htm') do (
- htox32c.exe %%i
- )
- for /f "delims=" %%i in ('dir /b %wj3%\*.htm') do (
- htox32c.exe %%i
- )
- goto :loop
复制代码
作者: 老刘1号 时间: 2023-9-28 12:06
本帖最后由 老刘1号 于 2023-9-28 12:12 编辑
回复 25# aloha20200628
我说了楼主那个 exe 可以并行了吗?
解决方案我没在下边回复吗?
下次回复麻烦自己先 bing 理解一下锁和 peterson 算法是干啥用的。
作者: aloha20200628 时间: 2023-9-28 12:57
回复 27# 老刘1号
Bing一通即可定‘是否’吗?
断定别人‘是否’,不也同时把自己抛入你所谓的‘无知’怪圈吗?
与您这种‘悬空回合’,对本贴具体而明确的探讨交流毫无帮助。到此结束吧!
作者: 77七 时间: 2023-9-28 13:25
回复 26# czjt1234
答案在15楼,楼主还要进行其它操作,同时开3个bat,大概说明 其它操作的时间需要占用2/3,htox32c.exe不能同时操作,限制了脚本效率,所以利用其它bat进行其它操作的时间,执行htox32c.exe,这样htox32c在三个bat中“接力”执行操作,把效率提到最高。
作者: 老刘1号 时间: 2023-9-28 13:34
回复 28# aloha20200628
有民科那味了,你看看
让看资料也不看,咬着 bing 四个字母不放
peterson 算法是 bing 写的吗?
我说 bing 是体谅您的理解能力,直接发几篇论文原文请问您老看得懂吗?model checking 您会吗?
悬空回合?一点也不悬空,反倒是您老一上来就通篇废话,踩一捧一,误导大众。
但凡你能在帖子中写一个“锁”字,把问题引导到正确的方向上,我都得高看你一眼。
我也不是针对您老哈,无知不可怕,但是感受不到自己的无知,还喜欢误导别人的,抱歉我看不惯。
作者: czjt1234 时间: 2023-9-28 16:49
回复 29# 77七
楼主的其它操作,应该是将htm文件处理并保存为临时文件
那可不可以将临时文件名设定为国定格式,比如 *.tmp
并且原批处理不再调用htox32c.exe
然后用第四个批处理调用htox32c.exe
将for循环里的 dir *.htm 改为 dir *.tmp 这样子
用第四个批处理避开进程冲突
作者: idwma 时间: 2023-9-28 18:23
试试判断进程的方法- @echo off
- :ks
- copy /y 1.html 2.html
-
- tasklist|findstr "^htox32c.exe" >nul&&goto :ks
-
- htox32c /IP /O0 /U1+4 2.html
- del /q 2.html
-
- echo 其他语句
- if exist *.html goto ks
复制代码
作者: 老刘1号 时间: 2023-9-28 18:28
回复 32# idwma
不太行,假设三个进程同时执行,那么会同时通过5行的条件
或者 htox32c 结束后,其余所有等待进程都会同时进临界区,进而跑起来很多个 htox32c
作者: idwma 时间: 2023-9-28 18:38
回复 33# 老刘1号
加个随机延时可以缓解一下吧- @echo off
- :ks
- copy /y 1.html 2.html
-
- set /a r=%random%%%10
- timeout /t %r% >nul
- tasklist|findstr "^htox32c.exe" >nul&&goto :ks
-
- htox32c /IP /O0 /U1+4 2.html
- del /q 2.html
-
- echo 其他语句
- if exist *.html goto ks
复制代码
作者: 77七 时间: 2023-9-28 19:52
回复 31# czjt1234
应该可以,只是不知道楼主具体环境,代码如何写...
也可以把htox32c这行命令,写入 1.bat 2.bat 3.bat
第4个bat根据时间顺序执行这几个bat,执行后删除,原bat判断是否已经删除,然后执行下一步
作者: hlzj88 时间: 2023-9-28 21:10
谢谢大家!非常感谢!
回复 26楼 在前面回帖中已经提到我做的这个bat,需要既能被别人调用,也可独立完成运行。网页小的10几K,大的有2 300k,需要的时间是不固定,同时运行,被另外bat控制,不可以达到最快速度。而且在整体整理工具集中,已设计有一个bat作为调度工具。
回复 33楼 tasklist在前期已经作为方法测试了,不能避免。因为瞬间可能启动两个htoX32c。
回复 大家 谢谢你们讨论这个问题,感觉有些过于热烈,有冒烟的效果了。。再次感谢!
作者: hlzj88 时间: 2023-9-28 21:29
本帖最后由 hlzj88 于 2023-9-28 21:44 编辑
问题已经完美解决了,特别感谢 77七 在18楼的建议。
下面说说我的处理方法:因为需要同时在3个文件夹内运行,他们之间排除tasklist不能满足的情况,最好就是判断他们上层文件夹是否有判断依据。但是这个依据也可能被两个同时判断到导致冲突,所以接受 77七 的建议,move走, 77七建议是move 走 exe ,我改为move 走标志文件,他们各自判断自己是否抢到标志文件,抢到的运行,并再次在上层给出标志文件供 抢。原理如此。
因为还有单独运行的可能,所以额外添加了不抢标志的判断。
下面是关键点的源码,我写的差,供大家理解斧正。
有一个先行条件,并用时,三个文件夹尾数需带数字,也许可以不用,我还没有考虑是否可以。- rem 多个复用避免冲突
- set tj=%~p0
- set tj=!tj:\=!
- set jh=!tj!
- echo !jh!
- for %%i in (1 2 3 4 5 6 7 8 9 0) do set tj=!tj:%%i=!
- set tj=!tj: =!
- echo !tj!
- echo !tj!>a.ini
- for /f "delims=" %%i in (a.ini) do set jh=!jh:%%i=!&&echo !jh!>b.ini
- findstr /i "1 2 3 4 5 6 7 8 9 0" b.ini&&echo, || echo,>abcd.ini
- rem 不用变量是同时几个变量容易被串用
- rem 在几个文件夹同时运行要求文件夹名称需末尾带数字。上面是判断是否是在几个文件夹同时运行,即便是带数字单一文件运行,也不影响正常运行。
- if not exist ..\a.ini (echo,>..\a.ini) else (ping /n 3 127.1)
复制代码
- if exist abcd.ini htox32c /IP /S1 /O0 testmm.html>nul 2>nul&&goto cl
- rem 下面开始抢权
- :ydx
- for /f "delims=" %%i in (b.ini) do (
- move /y ..\a.ini %%i.ini>nul
- if exist %%i.ini (htox32c /IP /S1 /O0 testmm.html>nul 2>nul) else (goto ydx)
- del /f/q %%i.ini>nul
- )
- goto :cl
-
- :cl
- if not exist abcd.ini echo,>..\a.ini
复制代码
再次谢谢大家!我都怀疑是否可以做到这功能,现三个文件夹各500+html已成功运行完成,无冲突。第一段放bat开头,第二段放需要抢权位置
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |