- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
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
- Etiquetas:
- Intel® Fortran Compiler
Enlace copiado
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
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.
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
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')
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
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.
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
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
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
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?
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
If it does, is there a way I can get around that (besides passing all the variables)?
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
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.
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
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.
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
[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
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
OPEN (NEWUNIT=iun, ...)
WRITE (iun....)
- Marcar como nuevo
- Favorito
- Suscribir
- Silenciar
- Suscribirse a un feed RSS
- Resaltar
- Imprimir
- Informe de contenido inapropiado
- Suscribirse a un feed RSS
- Marcar tema como nuevo
- Marcar tema como leído
- Flotar este Tema para el usuario actual
- Favorito
- Suscribir
- Página de impresión sencilla