Software Archive
Read-only legacy content

Multithreading

Intel_C_Intel
Employee
188 Views
I'm using Compaq Visual Fortran, ver. 6.5, and am having trouble
implementing the CreateThread call. The motivation for creating another
thread is not for parallel processing, it's because I'm making a
'recursive' call to a NAG subroutine (nag_nlp_sol), but that subroutine
does not support RECURSIVE calls. So, I'm trying to separate the data in
the two separate calls to nag_nlp_sol by running them in different
threads. The nag_nlp_sol routine is supposedly 'thread safe'.

Anyway, I'm not having success using multiple threads. I put together a
simple program that highlights the problem, while removing most of the
real program's complexity.

The following program takes a given value of 'x', set in a PARAMS module
(shared data for all routines), calls a subroutine to calculate y=x**2,
which in turn calls another subroutine to calculate z=y*1000. It works
in the form below (just using subroutine calls with no multithreading),
but apparently fails to enter MOD2 at all when I try to run the call to
'calcz' in a separate thread. Clearly, I'm making a fundamental error in
the way I'm trying to do this, but I don't know where and the thing
compiles without any errors.

Also, if I try to add a call to WaitForSingleObject, it fails miserably.
And, I'd like to use
CreateThread(0, 0, calcz, 0, 0, ThreadID)
instead of
CreateThread(0, 0, calcz, y1, 0, ThreadID)

(i.e., omit the parameter argument 'y1'), and just set the value of z
by calculating z=y*1000 in MOD2, but that causes more problems.

Any help would be appreciated. The program follows:

! Multithread test program - if working properly, the program
! takes an initial value of x, calls MOD1 to calculate
! y = x**2, which in turn calls MOD2 to calculate z = y * 1000.
!
! The program works in the form below, but does not work when
! an attempt is made to calculate z in a separate thread. Also,
! the WaitForSingleObject call is death.

MODULE PARAMS

IMPLICIT NONE
SAVE
INTRINSIC KIND
INTEGER, PARAMETER :: wp = KIND(1.0D0)

REAL(wp) :: x, y, z

DATA x /5.0_wp/

END MODULE PARAMS

!****************

MODULE MOD2

IMPLICIT NONE
CONTAINS

SUBROUTINE calcz(y1)

USE PARAMS
REAL(wp), INTENT (IN) :: y1

z = y1 * 1000

open(unit=5, file='c: est.out', status='unknown', action='write')
write (5,100)
100 format ('MOD2 reached.')

END SUBROUTINE calcz
END MODULE MOD2

!**************

MODULE MOD1

IMPLICIT NONE
CONTAINS

SUBROUTINE calcy(x1)

USE DFMT
USE PARAMS
USE MOD2, ONLY : calcz

INTEGER :: ThreadHandle, ThreadID, Err

REAL(wp), INTENT (IN) :: x1
REAL(wp) :: y1

y = x1**2
y1 = y

! The program works with the following CALL uncommented.
! However, if you comment-out the CALL and uncomment the
! CreateThread line, it doesn't work. If in addition you
! uncomment the WaitForSingleObject line, the program
! dies horribly.

CALL calcz(y1)

! ThreadHandle = CreateThread(0, 0, calcz, y1, 0, ThreadID)

! Err = WaitForSingleObject(ThreadHandle, WAIT_INFINITE)

END SUBROUTINE calcy
END MODULE MOD1

!**************

PROGRAM mt_test

USE PARAMS
USE MOD1, ONLY : calcy
IMPLICIT NONE

REAL(wp) :: x1

x1 = x

Call calcy(x1)

write (*,200) x, y, z
200 format ('x = ', f8.4, 2x, 'y = ', f8.4, 2x, 'z = ', f12.4,/)

END PROGRAM mt_test
0 Kudos
1 Reply
Intel_C_Intel
Employee
188 Views
Change your call to CreateThread, like so

ThreadHandle = CreateThread(0, 0, calcz, loc(y1), 0, ThreadID)

You can skip passing the fourth param,

ThreadHandle = CreateThread(0, 0, calcz, 0, 0, ThreadID)
but you'll have to change the signature of calcz in mod2 to accept no parameters and remove the declaration of dummy arg y1. Then all will work fine, including WaitForSingleObject.

I must admit though, that I have my doubts about the overall objective here. I'd be interested in hearing how it goes.

hth,
John
0 Kudos
Reply