Julia Fischer
Julia Fischer

Reputation: 21

python thread with os.chdir and c/fortran Program

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

Answers (2)

agentp
agentp

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

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

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

Related Questions