2016-08-16 2 views
1

У меня есть подпрограмма Fortran, которая вызывается несколько раз в основной программе (к которой у меня нет доступа). В моей подпрограмме я хочу читать данные из одного из нескольких файлов (~ 10^4) на каждой итерации на основе входного аргумента. Каждый из файлов имеет одну строку данных; и формат моих данных выглядит следующим образом:Чтение многих файлов в подпрограмме Fortran

0.97014199999999995  0.24253600000000000  0.0000000000000000  

Я использую следующие строки кода, чтобы открыть и прочитать файлы:

 program test_read 
     implicit none 
     integer :: i, iopen_status, iread_status 
     real :: gb 
     CHARACTER(len=25) :: filename 
     CHARACTER(*), PARAMETER :: fileplace = 
    & "/home/ajax/hexmesh_readn/G3/" 
     dimension gb(3) 

     i = 5 
     WRITE(filename,'(a,I0,a)')'GBn_',i,'.txt' 
     open(unit=15, 
    & file=fileplace//filename,IOSTAT=iopen_status) 
     read (15,*,IOSTAT=iread_status) gb 
     print *,"gb",gb(1),gb(2),gb(3) 
     close(15) 
     end program test_read 
  • В основной программе, я это переменная, но у меня есть файл для всех возможных значений i.
  • Теперь этот код работает отлично, когда я запускаю свою локальную машину. Но, когда я отправляю его вместе с основной программой, он ведет себя несколько странно. В частности, он читает некоторые файлы, но не другие.
  • Когда я распечатываю IOSTAT для открытия и чтения, я вижу, что IOSTAT для open равен 0 для всех файлов, тогда как для команды read используется 0 для некоторых, -1 для некоторых и 29 для других! Я посмотрел, что означает код ошибки 29, и я узнал, что это может означать, что файл не найден в пути. Но файл определенно определен.
  • Кроме того, я не вижу ничего другого в файлах, которые он не умеет читать. На самом деле, я даже видел тот же файл, дающий значение IOSTAT 0 и 29!
  • Следует отметить, что я запускаю основную программу на нескольких ядрах. Может ли это иметь какое-либо отношение к ошибке?
+0

Я предполагаю, что вы используете источник фиксированной формы, поэтому, пожалуйста, обратите внимание на форматирование кода (вы, вероятно, просто хотите отступать еще четырьмя столбцами). Мой совет [в другом месте] (http://stackoverflow.com/a/38614752) использовать спецификатор 'iomsg =' (и проверять значения iostat при использовании 'iostat =') здесь. – francescalus

+0

Похоже, что 'iomsg' доступен только в Fortran 2003, но я использую Fortran 90. Также, где вы имеете в виду, я должен отступать на 4 столбца? Перед первой колонкой? – Ajax

+2

С 'iomsg =', просто попробуйте. Это может не сработать для вашего компилятора, но в настоящее время очень популярны только компиляторы Fortran 90 (и не так много компиляторов Fortran 2003). И стоит отметить, что ваш код в вопросе не Fortran 90. – francescalus

ответ

1

Вы используете несколько экземпляров одной и той же программы одновременно? В некоторых операционных системах разные программы не могут одновременно открывать один и тот же файл. Указание того, что вы хотите доступ только для чтения, может разрешать доступ несколькими программами. В открытом заявлении Fortran: action='read'.

Если вы используете многопоточную программу, то разные потоки могут выполнять IO одновременно в разных файлах ... для предотвращения конфликтов должны использоваться разные номера единиц в каждом потоке.

+0

Меня больше беспокоит то, что он может просто открыть слишком много файлов из одного процесса и превысить ограничение ОС на открытых файлах. –

+0

Код показывает, что файл закрыт, поэтому, вероятно, количество файлов в процессе не является проблемой. –

+0

Итак, выясняется, что разные потоки пытались получить доступ к одному файлу в соответствии с его номером. Я решил это, используя номер переменной единицы, который является функцией ввода ('i' в приведенном выше коде). – Ajax