I'm trying to implement a code where we spawn a child process who should add one to the variable sum
at each iteration. We have at all 3 iteartions.
The result of sum
is : 0+1+1+1 = 3.
But when I want to spawn 3 threads in the child process part (so each thread will have an iteration), I get a sum
equal to 9.
(I'm new to POSIX Threads and to all the functions that I will use later so don't get surprised if the error is obvious, please)
Here is my code:
program main
use, intrinsic :: iso_c_binding
use :: unix
implicit none
integer :: i, rc,pid, STATUS,any_child
integer, parameter :: NTHREADS = 3
type(c_pthread_t) :: threads(NTHREADS)
integer, target :: routines(NTHREADS) = [ (i, i = 1, NTHREADS) ]
integer :: sum=0,product=5
pid = c_fork()
if (pid < 0) then
! Fork failed.
call perror('fork()' // c_null_char)
else if (pid == 0) then
print '(a)', '>>> child process running ...'
do i = 1, NTHREADS
! Create new thread.
rc = c_pthread_create(threads(i), c_null_ptr, c_funloc(compute), c_loc(routines(i)))
end do
do i = 1, NTHREADS
! Join thread.
rc= c_pthread_join(threads(i), c_loc(routines(i)))
end do
print '(a)', '>>> child process done.'
call exit(STATUS)
else
! Parent process.
print*,'habibi'
any_child=c_wait(STATUS)
print*,'ya nour 3in'
open(2,file='variables.dat')
read(2,*) sum,product
close(2)
print*,'The sum is equal to : ',sum
print*,'The product is equal to : ',product
end if
contains
recursive subroutine compute(arg) bind(c)
!! Runs inside a thread and prints out current thread id and loop
!! iteration.
type(c_ptr), intent(in), value :: arg
integer, pointer :: n
integer :: i, rc
integer :: sum=0,product=5
if (.not. c_associated(arg)) return ! Check whether argument has been passed.
call c_f_pointer(arg, n) ! Convert C pointer to Fortran pointer.
do i = 1, 3
sum=sum+1
product=product*2
open(1, file = 'variables.dat')
write(1,*) sum,product
close(1)
print '("--- Thread #", i0, " - Loop iteration ", i0)', n, i
rc = c_usleep(10**6) ! Sleep 1 sec.
end do
end subroutine compute
end program main
Here is the output:
habibi
>>> child process running ...
--- Thread #1 - Loop iteration 1
--- Thread #3 - Loop iteration 1
--- Thread #2 - Loop iteration 1
--- Thread #1 - Loop iteration 2
--- Thread #3 - Loop iteration 2
--- Thread #2 - Loop iteration 2
--- Thread #1 - Loop iteration 3
--- Thread #3 - Loop iteration 3
--- Thread #2 - Loop iteration 3
>>> child process done.
ya nour 3in
The sum is equal to : 9
The product is equal to : 2560
and here is how I compiled: gfortran -o fork fork.f90 libfortran-unix.a -lpthread
Can anyone explain why I got a sum
equal to 9 and what should I do to fix it ? I want the sum
to be equal to 3 so that each thread add 1 to the first value (which is 0).