我正在尝试使用pthreads进行多线程处理。我正在用构造函数创建池。第一个参数是工人数量。
$pool = new Pool(8, 'WebWorker');
我想自动检测处理器内核的计数。类似这样的东西:
$pool = new Pool(get_processor_cores_number(), 'WebWorker');
PHP是如何实现的?
如果服务器是Linux机器,您可以使用以下代码段:
$ncpu = 1;
if(is_file('/proc/cpuinfo')) {
$cpuinfo = file_get_contents('/proc/cpuinfo');
preg_match_all('/^processor/m', $cpuinfo, $matches);
$ncpu = count($matches[0]);
}
您可以这样做,当然您的服务器应该在linux:中
function get_processor_cores_number() {
$command = "cat /proc/cpuinfo | grep processor | wc -l";
return (int) shell_exec($command);
}
您将执行一个shell命令,然后将其强制转换为int。
如果有人在寻找一个简单的功能,以获得Windows和Linux两种操作系统的总CPU核心。
function get_processor_cores_number() {
if (PHP_OS_FAMILY == 'Windows') {
$cores = shell_exec('echo %NUMBER_OF_PROCESSORS%');
} else {
$cores = shell_exec('nproc');
}
return (int) $cores;
}
这里有一个暴露sysconf的扩展:krakjoe/sysconf
<?php
$cpusConfigured = sysconf(SYSCONF_NPROCESSORS_CONF);
$cpusOnline = sysconf(SYSCONF_NPROCESSORS_ONLN);
?>
大多数应用程序只关心配置的数量。
尽可能避免启动一个全新的shell来从操作系统中获取简单信息。这非常慢,而且占用内存,因为您要为一个简单的任务生成整个命令解释器。
这里有一个在Linux或Windows上快速完成的功能,它不需要生成一个全新的外壳:
function get_total_cpu_cores() {
return (int) ((PHP_OS_FAMILY == 'Windows')?(getenv("NUMBER_OF_PROCESSORS")+0):substr_count(file_get_contents("/proc/cpuinfo"),"processor"));
}
这将适用于任何半现代的windows安装(至少从windows 95开始),并将适用于大多数(如果不是全部的话)Linux版本,前提是您有权读取/proc/cpuinfo。但大多数装置都让这个世界可读。。。所以应该不会有任何问题。
需要进一步注意的是,从技术上讲,这将向您展示操作系统所看到的可用CPU内核。Windows和Linux都将超线程CPU线程视为内核,即使它们不是物理内核。也就是说,除非你真的需要知道机器上物理核心的数量,否则这仍然适用于你想要做的事情。然后你将进入一个更加复杂的过程。
希望这能有所帮助!
在我自己的库中,我有一个用于此功能的函数。您可以在它使用非标准PHP函数的地方轻松地对其进行修改。
例如,我缓存结果,这样您就可以忽略它。然后我有一些功能来检查我们是否在Linux、Mac或Windows上运行。你可以在那里插入一张类似的支票。为了执行实际的系统特定检查,我使用自己的Process
类,它允许在后续请求中重新连接到正在运行的进程,以检查状态、输出等。但您可以更改它,只使用exec
。
public static function getNumberOfLogicalCPUCores() {
$numCores = CacheManager::getInstance()->fetch('System_NumberOfLogicalCPUCores');
if(!$numCores) {
if(System::isLinux() || System::isMac()) {
$getNumCoresProcess = new Process("grep -c ^processor /proc/cpuinfo");
$getNumCoresProcess->executeAndWait();
$numCores = (int)$getNumCoresProcess->getStdOut();
}
else if(System::isWindows()) {
// Extract system information
$getNumCoresProcess = new Process("wmic computersystem get NumberOfLogicalProcessors");
$getNumCoresProcess->executeAndWait();
$output = $getNumCoresProcess->getStdOut();
// Lazy way to avoid doing a regular expression since there is only one integer in the output on line 2.
// Since line 1 is only text "NumberOfLogicalProcessors" that will equal 0.
// Thus, 0 + CORE_COUNT, which equals CORE_COUNT, will be retrieved.
$numCores = array_sum($getNumCoresProcess->getStdOutAsArray());
}
else {
// Assume one core if this is some unkown OS
$numCores = 1;
}
CacheManager::getInstance()->store('System_NumberOfLogicalCPUCores', $numCores);
}
return $numCores;
}