Page 1 of 1

Synchronization of file count

Posted: 16 Nov 2009 08:03
by hugobs
Hi,

I'm having a problem a synchronization problem between dir and counting the nr of files with a given extension.

What I'm trying to the is the following:

1. All files with the extension *.abc in the current directory should be submitted for execution
2. A fluid dynamics simulation is started, which generates a *.RUN file for each calculation file. This has been mimicking in the code I'm posting with copy n_max.txt %filename%.RUN
3. However, I don't want the nr of files running simultaneously to exceed the value contained in the file n_max.txt (the file contains just one integer, for instance 2)

So, if the number of calculation already running (nr of *.RUN files) is less than n_max, a new calculation is started, otherwise it loops back to the beginning

This works fine, except that counting the nr of calculations already running is a big sluggish. It takes too long for the program to notice that a new Run file has been created, leading to the number of running cases exceeding the limit.

For instance:
Create a file called n_max.txt ( echo 2 > n_max.txt )
Create 3 files A1.abc, A2.abc, A3.abc
Create 1 file A1.RUN (This means, 1 process is running out of a max of 2)
start the batch... only calc A2 should start, since n_max is reached
Calculation A2 AND A3 are started. When the loop tries to start A3, notice how the dir command clearly shows that there are 2 files, but the count is still 1.

In the next loop, it recognizes that there is a total of 3 files. It appears that the system does not immediately register the newly created A2.RUN

What am I doing wrong? How can I force it to get the latest count?
I tried imposing a 5s delay with the ping, and have tried writing the program in many different way, but the behavior doesn't change.

Thanks in advance

Code: Select all

@ECHO OFF
:Big_loop
rem read max nr of processes
for /f %%a in ('type n_max.txt') do (set /a b=%%a)
rem find files with extension abc
for /f %%n in ('dir /b ^| find ".abc"') do (
   set /A c=0
   for %%f in (*.RUN) do (set /A c+=1)
   rem next line just for comparison
   dir *.RUN
   echo max %b% processes allowed, %c% running
   if %b% gtr %c% (
      call:Run_file %%n
      ping -n 5 127.0.0.1 > nul
      )
   )

timeout /T 5 /NOBREAK
goto Big_loop
goto:eof

:Run_file

set b=%1
set filename=%b:.abc=%

echo starting %1%
copy n_max.txt %filename%.RUN
goto:eof

Posted: 18 Nov 2009 09:57
by avery_larry
It's a classic delayed variable expansion problem. Whenever you evaluate a piece of code that is inside parentheses (a for loop, for example), the variable are evaluated only once -- when the code inside the parentheses is called.

In your code you are incrementing the c variable inside a for loop, but the code that evaluates the value of the c variable will NOT see the NEW value of the variable, because it already evaluated it when the for loop was initially called.

The solution is to use delayed variable expansion. Whenever you want to use the current value of a variable, you use !c! instead of %c% (provided you've enabled delayed variable expansion).

So without testing the code, I have this suggestion:

Code: Select all

@ECHO OFF
setlocal enabledelayedexpansion

:Big_loop
rem read max nr of processes
for /f %%a in ('type n_max.txt') do (set /a b=%%a)
rem find files with extension abc
for /f %%n in ('dir /b ^| find ".abc"') do (
   set /A c=0
   for %%f in (*.RUN) do (set /A c+=1)
   rem next line just for comparison
   dir *.RUN
   echo max %b% processes allowed, !c! running
   if %b% gtr !c! (
      call:Run_file %%n
      ping -n 5 127.0.0.1 > nul
      )
   )

timeout /T 5 /NOBREAK
goto Big_loop
goto:eof

:Run_file

set b=%1
set filename=%b:.abc=%

echo starting %1%
copy n_max.txt %filename%.RUN
goto:eof

Posted: 20 Nov 2009 03:29
by hugobs
Thank you avery_larry. :oops:

You were right.

It works fine now.