I'm trying to make calls of a Fortran method simultaneously in different threads. The executions are completely independent from each other and the main thread. The problem is that using module variables means that the variables are made global by the dll, meaning the two calls would use it, thus instacrashing the program, and so it happens. This is my interpretation, based on this answer of Bálint Aradi.
C#
static void Main(string[] args)
{
RunTwiceSync();//WORKS
RunTwiceAsync();//INSTACRASH
}
private static void RunTwiceSync()
{
TestMyArray();
TestMyArray();
}
private static void RunTwiceAsync()
{
ThreadStart ts = new ThreadStart(() =>
{
TestMyArray();
});
Thread t = new Thread(ts);
t.Start();
TestMyArray();
}
private static void TestMyArray()
{
Console.WriteLine("START");
int size = 52;
float[] myarray = new float[size];
sub_(ref size, myarray);
Console.WriteLine(myarray.Select(x => x.ToString()).Aggregate((x, y) => x + ";" + y));
Console.ReadLine();
}
[DllImport("FortranArraySimpleTest.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void sub_(ref int size, float[] myarray);
FORTRAN
!DEC$ ATTRIBUTES DLLEXPORT::ingammaextern
subroutine sub(size, myarray)
use module1 ! * REMOVING MODULE USAGE FIXES THE PROBLEM
implicit none
INTEGER :: size
integer :: assignme
REAL, dimension(1:size) :: myarray
assignme = size
allocate(alocarray(1:assignme))
deallocate(alocarray)
end subroutine
! ************************************begin another file***********
MODULE module1
IMPLICIT NONE
real, dimension(:), allocatable :: alocarray
END MODULE module1
This solution, the removal of modules, is extremely cumbersome and a maintenance major headache, due to the code which made me post the question being very large.
Environment: GNU Fortran Compiler, windows 7 64bits, CodeBlocks for fortran, VS2012, i didn't change any compiler options.
Any ideas?
Thank you for your time
What can be done is to change the module for a derived type, which is then passed with every call
module orig
use whatever
interfaces
small types
variables
contains
procedures
end module
to
module state_class
use whatever
interfaces
small types
shared variables
type state
non shared variables
contains
procedure :: the procedures
(not obligatory)
end type
contains
procedures changed to accept one additional argument:
a passed dummy argument class(state)
or just a regular dummy argument type(state)
end module
Every thread has own state
class instance and passes it explicitly or as a passed dummy argument.