2015-04-07 2 views
1

Программное обеспечение, которое я использую, поддерживает несколько потоков и интерфейс TCL. Поэтому я не уверен, как найти количество процессоров в TCL, чтобы ограничить максимальные потоки.Как найти количество процессоров в tcl?

+0

Платформа? Linux или Windows? –

+0

Это должна быть кросс-платформа. Потому что он будет использоваться как на windows, так и на linux. –

+0

Не слишком чистая, кросс-платформенная. В Linux чтение/proc/cpuinfo предоставляет вам информацию. Попробуйте cat/proc/cpuinfo –

ответ

0

Код первоначально получен из ответа @ DonalFellows. Но у меня все еще возникает проблема с sysctl, которая существует в Ubuntu, но у нее нет hw.ncpu.

Так что я сделал некоторые изменения на нем.

proc number_of_processor {} { 
    global tcl_platform env 
    switch ${tcl_platform(platform)} { 
     "windows" { 
      return $env(NUMBER_OF_PROCESSORS)  
     } 

     "unix" { 
      if {![catch {open "/proc/cpuinfo"} f]} { 
       set cores [regexp -all -line {^processor\s} [read $f]] 
       close $f 
       if {$cores > 0} { 
        return $cores 
       } 
      } 
     } 

     "Darwin" { 
      if {![catch {exec {*}$sysctl -n "hw.ncpu"} cores]} { 
       return $cores 
      } 
     } 

     default { 
      puts "Unknown System" 
      return 1 
     } 
    } 
} 

Пробовал на Ubuntu и Windows 7, это работает. У меня нет MacOS вокруг меня. Так что это будет хорошо, если кто-то сможет проверить, что работает, или нет.

3

В Tcl ничего не встроено; это обсуждается, но не действует, потому что количество ЦП не обязательно является числом , что процесс может использовать (безусловно, самая важная причина для получения информации). Тем не менее, информация доступна. Просто так, как вы получаете информацию, зависит от платформы.

proc numberOfCPUs {} { 
    # Windows puts it in an environment variable 
    global tcl_platform env 
    if {$tcl_platform(platform) eq "windows"} { 
     return $env(NUMBER_OF_PROCESSORS) 
    } 

    # Check for sysctl (OSX, BSD) 
    set sysctl [auto_execok "sysctl"] 
    if {[llength $sysctl]} { 
     if {![catch {exec {*}$sysctl -n "hw.ncpu"} cores]} { 
      return $cores 
     } 
    } 

    # Assume Linux, which has /proc/cpuinfo, but be careful 
    if {![catch {open "/proc/cpuinfo"} f]} { 
     set cores [regexp -all -line {^processor\s} [read $f]] 
     close $f 
     if {$cores > 0} { 
      return $cores 
     } 
    } 

    # No idea what the actual number of cores is; exhausted all our options 
    # Fall back to returning 1; there must be at least that because we're running on it! 
    return 1 
} 

Обратите внимание, что если вы хотите, чтобы узнать количество процессоров для запуска на то, что вы действительно хотите это количество бит в маске сродства CPU. К сожалению, получение этой информации на большинстве платформ нетривиально.

+0

Привет @Donal Спасибо за ваш ответ. У меня появилась идея. Но в вашем коде есть две проблемы. Первая - это опечатка для платформы Linux, вы устанавливаете переменную 'cores', но возвращаете' cpu_cores'. Другой - для проверки «OSX». Мой 'Ubuntu' тоже получил' sysctl'. Поэтому он не может вернуть правильный результат. Мне нужно поменять проверочную последовательность, чтобы она работала в Linux. –

+0

@EnzoChi Должно быть исправлено сейчас. Извини за это. (Я тестировал Debian и OSX, но Ubuntu должен был быть другим ...) –

0

Я пробовал оба решения выше. @DonalFellows была почти идеальна, но не работала на моем OSX, поскольку tclsh по умолчанию был 8.4, а синтаксис {*} для exec не работал. Однако конструкция {*}, казалось, не требовалась, поскольку ее удаление позволяло ей работать с tclsh 8.4, 8.5 и 8.6.

Я вставлял код ниже с этим изменением, поскольку у меня недостаточно репутации, чтобы просто комментировать.

proc numberOfCPUs {} { 
    # Windows puts it in an environment variable 
    global tcl_platform env 
    if {$tcl_platform(platform) eq "windows"} { 
     return $env(NUMBER_OF_PROCESSORS) 
    } 

    # Check for sysctl (OSX, BSD) 
    set sysctl [auto_execok "sysctl"] 
    if {[llength $sysctl]} { 
     if {![catch {exec $sysctl -n "hw.ncpu"} cores]} { 
      return $cores 
     } 
    } 

    # Assume Linux, which has /proc/cpuinfo, but be careful 
    if {![catch {open "/proc/cpuinfo"} f]} { 
     set cores [regexp -all -line {^processor\s} [read $f]] 
     close $f 
     if {$cores > 0} { 
      return $cores 
     } 
    } 

    # No idea what the actual number of cores is; exhausted all our options 
    # Fall back to returning 1; there must be at least that because we're running on it! 
    return 1 
} 
Смежные вопросы