Reputation: 21
I am having some troubles by understanding my python with C or FORTRAN code.
I have a Python script that simply deploys two threads, each thread will go into a sub-directory and call the same Fortran Program (for the same of simplicity with os.system, but Popen is the same. I also included a C Program to show the same problem )
When each instance of a.out (F77 or C) is called, I was expecting that they know in which CWD they are, but 1 out of 10 or 20 runs, they don't. So I think I am doing something wrong with my python.
When running the Python script with the F77 code I got this error:
CWD_F: /home/usr/f_fail/2
CWD_F: /home/usr/f_fail/2
Fortran runtime error: Cannot open file 'dummy.txt': File exists
When running with C sometimes I get
CWD_C : /home/usr/f_fail/2
CWD_C : /home/usr/f_fail/2
Here is my very simple python. One thing; when I uncomment the time.sleep() it seems to work well!
#!/usr/bin/python
import threading, os,time
def t1( newDir ):
os.chdir( newDir )
os.system('../a.out')
os.chdir('..')
def t2( newDir ):
os.chdir( newDir )
os.system('../a.out')
os.chdir('..')
#main starts here
cwd_=os.getcwd()
try :
os.mkdir('1')
except:
pass
try :
os.mkdir('2')
except:
pass
newDir1=os.path.join( cwd_ , '1')
newDir2=os.path.join( cwd_ , '2')
tt1 = threading.Thread( target=t1 , args=(newDir1,))
tt2 = threading.Thread( target=t2 , args=(newDir2,))
tt1.start()
#time.sleep(1)
tt2.start()
tt1.join()
tt2.join()
Here the FORTRAN77 code :
program test
implicit none
integer i,k,unt
real*8 a(3,10 ), c(3)
character*132 fl,cwdpath
do i=1,10
c(1)=i*1.11
c(2)=i*2.22
c(3)=i*3.33
a(:,i)=c
enddo
unt=1
fl='dummy.txt'
call getcwd(cwdpath)
write(*,*) 'CWD_F: ', cwdpath
write(*,*) 'unit: ', unt
open(unt,file=fl,status='unknown')
close(unt,status='delete')
open(unt,file=fl,status='new')
do k=1,10
write(unt,200) a(1,k),a(2,k),a(3,k)
enddo
close(unt)
200 format(' ',F10.4,F10.4,F10.4)
end
Alternatively, here is my C code:
#include <unistd.h>
#include <stdio.h>
#define PATH_MAX_ 1024
int main() {
char cwd[PATH_MAX_];
if (getcwd(cwd, sizeof(cwd)) != NULL)
fprintf(stdout, "CWD_C : %s\n", cwd);
return 0;
}
Any help or idea will be greatly appreciated. Cheers !! Julia
Upvotes: 1
Views: 250
Reputation: 6999
since you have passed the path to the executable, all you need to do is use the path when you open the file:
open(unt,file=trim(cwdpath)//'/dummy.txt',status='unknown')
Upvotes: 1
Reputation: 799540
The CWD is process-wide, so here's what happens: First, os.chdir()
in one of the threads is executed, switching the process to that directory. Then, os.chdir()
in the other thread is executed, switching the process to the other directory. Then the rest of the code in the threads is run. You will need to serialize the thread operations in order to make the code work correctly.
Alternatively you can tell a shell to change directories before running the program; since each shell is a separate process there is no conflicting directory change, and also no need to return to the parent directory afterwards.
Upvotes: 2