【问题标题】:Get system information with Fortran使用 Fortran 获取系统信息
【发布时间】:2018-03-08 03:39:40
【问题描述】:

我有兴趣通过 Fortran 获取系统信息 - 类别可能包括:

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

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

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

这是第 1 类的有效解决方案,但仍保留第 2 - 4 类。

谢谢!

【问题讨论】:

  • 您可能应该看看内部例程execute_command_lineget_environment_variable
  • 不要忘记 2-4 在 Windows 和 Linux 之间会有所不同。最好只问一个问题,因为您的观点可能需要不同的方法。
  • 确实很棒,但并非没有“问题”。我认为第一个问题是对execute_command_line 的调用中命令的执行发生在子环境中(或者在您的平台上调用它们的任何东西),因此任何设置(例如环境变量)都会在子环境中消失-environment 完成运行。所以环境变量不在get_environment_variable 钓鱼的环境中。我认为最简单的组合是......
  • ... 让命令行写入文件,例如execute_command_line("getconf _NPROCESSORS_ONLN > nprocs.dat",wait=.true.) 之类的东西,你稍后会读到。
  • 调用相关的C函数;以uname(2)sysconf(3) 开头

标签: fortran gfortran fortran90 preprocessor


【解决方案1】:

你可以在 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 不是很有帮助。我认为这是一个错误。 ifort 根本没有COMPILER_VERSION();也许这只是因为我有两个编译器的旧版本。无论如何,如果您可以从COMPILER_VERSION() 字符串中获取操作系统,您就会知道如何在Windows 中加载有用的函数,例如LoadLibraryGetProcAddress。然后,如果您有正确的操作系统,则创建具有所需操作系统过程名称的参数,如果没有,则创建存根过程的名称。

   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】:

    一旦您按照问题中显示的方式完成了第 1 点,您就可以继续其他点。

    在 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(只需重定向标准输出)。

    在 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 的了解为零。您的问题非常(太?)宽泛,所以我认为只回答其中的一部分是可以接受的。

    【讨论】:

      【解决方案3】:

      我在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
      

      我使用帮助from 获取架构。一般子程序call system(String_variable) 启动命令行并获取系统命令。类似地,它在 Ubuntu 中启动终端并获取 shell 命令。 (不同操作系统的系统命令明显不同。)

      【讨论】:

        猜你喜欢
        • 2018-06-07
        • 2012-05-07
        • 2011-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多