使用Fortran获取系统信息

3

我希望通过Fortran获取系统信息,包括以下分类:

  1. 操作系统名称
  2. 操作系统版本
  3. CPU架构(32位/64位)
  4. 核心数量

据我的了解,您可以通过预处理指令获取基本的操作系统信息,例如

#ifdef _WIN32
  print *,'Windows'
#ifdef _APPLE_
  print *,'macOS'
#ifdef __linux
  print *,'Linux'
#endif

这是针对第一类的一个有效解决方案,但仍然留有2-4类问题。
谢谢!

1
你可能应该查看内置例程execute_command_lineget_environment_variable - High Performance Mark
2
不要忘记,Windows和Linux之间的2-4将有所不同。最好提出一个单一问题,因为您的分数可能需要不同的方法。 - Vladimir F Героям слава
1
确实很棒,但并非没有“问题”。我认为第一个问题是,在调用execute_command_line时,命令的执行发生在子环境中(或者在您的平台上称为什么),因此任何设置,例如环境变量,在子环境完成运行后就会消失。因此,环境变量不在get_environment_variable查找的环境中。我认为最简单的解决方法是... - High Performance Mark
2
要让命令行写入文件,例如像 execute_command_line("getconf _NPROCESSORS_ONLN > nprocs.dat",wait=.true.) 这样,然后再读取该文件。 - High Performance Mark
1
调用与此相关的C函数;从uname(2)sysconf(3)开始。 - Basile Starynkevitch
显示剩余2条评论
3个回答

3

在Fortran中,你可以做到所有这些事情,但实际上并不完全如此。从ISO_FORTRAN_ENV模块中获取的COMPILER_VERSION()字符串至少应该提供操作系统的名称。通过这个你就知道要调用哪些程序来获取更多信息。

program test
   use ISO_C_BINDING
   use ISO_FORTRAN_ENV
   implicit none
   integer, parameter :: bitness = bit_size(0_C_INTPTR_T)
   write(*,'(*(g0))') 'This is a ',bitness,'-bit system.'
   write(*,'(*(g0))') COMPILER_VERSION()
end program test

这是我的gfortran输出结果:
This is a 64-bit system.
GCC version 7.2.0

所以gfortran并不是很有用。我认为这是一个bug。ifort根本没有COMPILER_VERSION();也许这只是因为我有两个编译器的旧版本。无论如何,如果您可以从COMPILER_VERSION()字符串中获取操作系统信息,那么您就会知道如何在Windows中加载有用的函数,比如LoadLibraryGetProcAddress。然后,如果您有正确的操作系统,您可以创建具有所需OS过程名称的参数,否则创建一个存根过程的名称。

   logical, parameter :: v0 = index(v5,'WINDOWS') /= 0
   character(*), parameter :: v6 = merge('LoadLibraryA','Stub12345678',v0)
   interface
      function LoadLibrary(lpFileName) bind(C,name=v6)
         import
         implicit none
!DEC$ ATTRIBUTES STDCALL :: LoadLibrary
!GCC$ ATTRIBUTES STDCALL :: LoadLibrary
         integer(C_INTPTR_T) LoadLibrary
         character(kind=C_CHAR) lpFileName(*)
      end function LoadLibrary
   end interface

那样你就可以在Windows中访问 LoadLibrary 而不会导致未满足的外部引用。不幸的是,gfortran 认为将绑定名称替换为命名常量而不是字符文字是无效的。
但原则上,您可以使用编译器告诉您操作系统名称并设置您需要向操作系统请求其余信息的一些关键函数,但这需要比我拥有的更高级的编译器。如果您有更好的编译器,我可以编辑更多内容,然后您可以查看它是否在您的计算机上崩溃。

2

在你按照问题中展示的方式完成了第一步后,你可以继续执行其他步骤。

在POSIX系统(包括Linux)中,你可以执行以下命令:

uname -a

获取操作系统名称和版本信息,例如:

Linux meop37 4.4.104-18.44-default #1 SMP Thu Jan 4 08:07:55 UTC 2018 (05a9de6) x86_64 x86_64 x86_64 GNU/Linux

你可以将这个内容存储到一个文件中,并在Fortran中读取该文件(只需重定向stdout)。

在Linux中,你可以读取/etc/os-release来查找操作系统的版本。

在我的情况下,它包括:

NAME="openSUSE Leap"
VERSION="42.2"
ID=opensuse
...

在Linux中,您可以读取/proc/cpuinfo来获取有关CPU的大量信息(包括您要求的信息)。在Fortran中,解析此信息是您的责任。
在我的情况下,它包含以下内容:
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
stepping        : 9
microcode       : 0x1c
cpu MHz         : 1693.800
cache size      : 8192 KB
physical id     : 0
siblings        : 8
core id         : 0
cpu cores       : 4
...

我对MS Windows毫无了解。你的问题非常(太?)广泛,因此我认为只回答其中一部分是可以接受的。


0

我可以提供关于Windows 10的架构和详细系统信息的答案。(可能也适用于其他Windows系统。)

program info
implicit none
print*,'detail system information: (on Windows 10)'
call system('SystemInfo')
print*
read(*,*)
print*,'system architecture:'
call system('wmic OS get OSArchitecture')
print*
end program

我使用了help来获取架构。通常子程序call system(String_variable)启动cmd行并获取系统命令。类似地,它在Ubuntu中启动终端并获取shell命令。(不同操作系统的系统命令显然是不同的。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接