- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The file name should be different for each thread. I wrote a sample with a different file name for each thread.
Where am I going wrong?
subroutine FTHREAD(dcalc,tID)
implicit double precision(a-z)
!DEC$ ATTRIBUTES DLLEXPORT :: FTHREAD
integer uin,uout,tID
character*256 ain,aout
character char
integer int
real float,array(8)
namelist /test/ char,int,float,array
if(tID.eq.0)then
ain='assump.dat'
aout='assump.out'
uin=10
uout=11
else
ain='assump2.dat'
aout='assump2.out'
uin=12
uout=13
endif
open(unit=uin,file=ain,status='old',form='formatted')
read(uin,test,ERR=999)
write(*,*) "FThread: tID = ",tID
write(*,*) "FThread: Assumption Read Complete."
close(uin)
open(unit=uout,file=aout,status='unknown')
write(uout,test)
close(uout)
return
999 write(*,*) "FThread: Error reading assumptions file."
return
end subroutine
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OPEN (NEWUNIT=iun,....)
and an unused unit is selected and returned to you in variable iun after the file is opened. Then make sure you always use the variable in your I/O statements.
Also be sure to select the property Fortran > Code Generation > Generate Reentrant Code > Threaded. This will inform the I/O library that it may be called from a threaded environment.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It does not work correctly every time. I'm still getting some crossover or something between the threads. I'm not sure exactly what it is though. It seems to me like the data from arrays 'dcalc' and 'array' are being overwritten by the second thread that executes. 'dcalc' is a REAL array that I added. The data in 'array' is read in from the assumptions files.
Code:
data uin/10,15/
data uout/11,16/
data ain/'assump.dat','test.dat'/
data aout/'assump.out','test.out'/
i=uin(tID+1)
j=uout(tID+1)
open(unit=i,file=ain(tID+1),status='old',form='formatted')
open(unit=j,file=aout(tID+1),status='unknown')
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How would the different threads be opening the same file?
I was assuming each thread would have it's own ID, and the file names could be accessed according to the thread ID. Stepping through the debug, it seems like it is accessing the same file, but I don't understand why.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the code below, the problem is writing to the out files. If I open the ".out" file with one of the two commented out open statements, the .dll runs fine. If I use the open statement that is not commented out, the 'b' CHARACTER out file name gets overwritten sometimes, and it trys to write to the same file twice (different units, same file name).
What is wrong with the code the way it's written? If the .dll is called from two seperate threads, why would the memory for the 'b' variable be shared betweent the two threads? Maybe it isn't, but why else would the variable be overwritten?? (Input files are hardcoded to be different file names)
This is confusing the crap out of me.
subroutine FTHREAD(a,dcalc,tID)
implicit double precision(a-z)
!DEC$ ATTRIBUTES DLLEXPORT :: FTHREAD
integer uin(8),uout(8),tID
integer i,j
character*256 a,b,ain(8),aout(8)
logical opend
real dcalc(1000)
character charac
integer int
real float,array(8)
namelist /test/ charac,int,float,array
data uin/10,15/
data uout/11,16/
data aout/'assump.out','test.out'/
i=uin(tID+1)
j=uout(tID+1)
b=a(1:index(a,"."))//"out"
write(*,*) "FThread: tID = ",tID," Open unit = ",i," File = ",a(1:15)
open(unit=i,file=a,status='old',form='formatted')
! open(unit=j,file=aout(tID+1),status='unknown')
! open(unit=j,file=a(1:index(a,"."))//"out",status='unknown')
open(unit=j,file=b,status='unknown')
read(i,test,ERR=999)
dcalc(5)=array(1)
write(*,*) "FThread: tID = ",tID," array(1) = ",array(1)
write(*,*) "FThread: tID = ",tID
write(*,*) "FThread: tID = ",tID," Assumption Read Complete."
close(i)
write(j,test)
close(j)
dcalc(6)=real(tID)
return
999 write(*,*) "FThread: tID = ",tID," Error reading assumptions file."
return
end subroutine
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So are all variables in static storage vulnerable to being overwritten in a multithreaded application?
Just out of curiousity, is there a way to make sure the 'B' variable isn't in static storage without using the RECURSIVE keyword before SUBROUTINE?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If it does, is there a way I can get around that (besides passing all the variables)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I found the compiler option /Qdyncom. Is that what I need to use? How would I apply that compiler option in Visual Studio? It would need to be applied to quite a few common blocks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In OpenMP, you can name COMMON blocks in a "threadprivate" directive, but this doesn't work in DLLs in Windows (a Windows limitation) and it would depend on the C application using OpenMP rather than its own threading.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[bash]! ********************************************************************** integer(kind=4) function getFreeUnit() ! ********************************************************************** logical(kind=4) test do getFreeUnit=10,999 inquire(getFreeUnit,opened=test) if (.not.test) return enddo getFreeUnit=-1 return end function getFreeUnit[/bash]Markus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OPEN (NEWUNIT=iun, ...)
WRITE (iun....)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page