0

我编写这个小代码是为了使其适应我的主代码并使用该fork/wait方法执行存储在array16 个任务中的任务(defined typefunction pointer指向要执行的子例程 +integer表示任务的状态)。

! fork.f90
program main
  use :: unix
  implicit none
  integer :: i, pid, STATUS,any_child
  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, 3
        ! Sleep for 1 second.
        print '(">>> step ", i0, " ...")', i
        sum=sum+1
        product=product*2 
        open(1, file = 'variables.dat')
        write(1,*) sum,product
        close(1)
     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

 
end program main
   

正如你在这里看到的(如果我理解得很好的话..),我们有一个子进程执行计算,父进程等待并打印一些东西。我遇到的问题是父进程打印的“sum”和“product”的值不正确。对于总和,我得到 0 作为值,就好像子进程完成的计算甚至没有发生一样。我考虑将子进程计算的值写入一个文件,该文件将由父进程读取。它有效!但是为了使它适应我的代码,我需要考虑很多事情:首先,我产生了 16 个子进程,而不仅仅是 1。其次,我有超过 15 个变量,而不仅仅是 2(总和和产品)。最后,

我将向您展示我的部分代码:

 number_children=16
          do ff =5,number_children+4
             if (tasks_ready_master(ff)%state==STATE_READY) then
                tasks_ready_master(ff)%state=STATE_RUNNING      
                pid=c_fork() !< spawn a child process 
                if (pid < 0) then 
                   call perror('fork()' // c_null_char) !< Error 
                else if  (pid == 0) then !< Child process              
                   call tasks_ready_master(ff)%f_ptr(self,var) !< execute the task
                   open(1, file = 'variables.dat')
                   write(1,*) var%pas_t
                   write(1,*) var%cpt_t
                   write(1,*) var%cpt1_t
                   write(1,*) var%nb_element_t
                   write(1,*) var%ww_t
                   write(1,*) var%dt_t
                   write(1,*) var%dx_t
                   write(1,*) var%p_element_t
                   write(1,*) var%u_prime_t
                   write(1,*) var%u_prime_moins_t
                   write(1,*) var%u_prime_plus_t
                   write(1,*) var%taux_t
                   write(1,*) var%grad_x_u_t
                   write(1,*) var%grad_t_u_t
                   write(1,*) var%grad_t_f_t
                   write(1,*) var%grad_x_f_t
                   write(1,*) var%flux_t
                   write(1,*) var%sm_t
                   write(1,*) var%ax_plus_t
                   write(1,*) var%ax_moins_t
                   write(1,*) var%ux_moins_t
                   write(1,*) var%ux_plus_t
                   write(1,*) var%tab0_t
                   write(1,*) var%tab_t
                   close(1)
                   tasks_ready_master(ff)%state=STATE_INACTIVE 
                   call exit(STATUS)
                else
                   any_child=c_wait(STATUS) !< wait for the child process 
                   if (any_child<0) then
                      stop 'error' !< Error 
                   end if

                end if
                open(2,file='variables.dat')
                read(2,*) var%pas_t
                read(2,*) var%cpt_t
                read(2,*) var%cpt1_t
                read(2,*) var%nb_element_t
                read(2,*) var%ww_t
                read(2,*) var%dt_t
                read(2,*) var%dx_t
                read(2,*) var%p_element_t
                read(2,*) var%u_prime_t
                read(2,*) var%u_prime_moins_t
                read(2,*) var%u_prime_plus_t
                read(2,*) var%taux_t
                read(2,*) var%grad_x_u_t
                read(2,*) var%grad_t_u_t
                read(2,*) var%grad_t_f_t
                read(2,*) var%grad_x_f_t
                read(2,*) var%flux_t
                read(2,*) var%sm_t
                read(2,*) var%ax_plus_t
                read(2,*) var%ax_moins_t
                read(2,*) var%ux_moins_t
                read(2,*) var%ux_plus_t
                read(2,*) var%tab0_t
                read(2,*) var%tab_t
                close(2)
             end if
          end do
       end if

如您所见,我编写并读取了多个变量。为了理解 var 是什么,这里是它的声明:

type(variables)::var !< the variables 

和:

  type::variables 
     INTEGER,pointer::pas_t,cpt_t,cpt1_t,nb_element_t,ww_t
     real(kind=REAL64),pointer :: dt_t,dx_t
     integer ,dimension(:),pointer::p_element_t
     real(kind=REAL64), dimension(:),pointer ::u_prime_t,u_prime_moins_t, u_prime_plus_t,taux_t,grad_x_u_t,&
          &grad_t_u_t,grad_t_f_t,grad_x_f_t,flux_t,sm_t
     real(kind=REAL64),dimension(:),pointer:: ax_plus_t,ax_moins_t,ux_moins_t,ux_plus_t
     real(kind=REAL64),dimension(:,:),pointer::tab0_t,tab_t
  end type variables

简单地说,它存储了我在计算和任务执行中需要的所有变量。

小代码效率高吗?我想避免使用管道。在这种情况下我该怎么办?如何避免我的程序变得非常慢?我应该使用 OpenMP 进行并行化吗?我想提一下,只有一个线程执行我之前展示的部分代码。

4

0 回答 0