Nick
Nick

Reputation: 10153

How to calculate number of processor cores in PHP script (linux)?

I'm trying to use pthreads for multithreading. I'm creating pool with constructor. First parameter is number of Workers.

$pool = new Pool(8, 'WebWorker');

I want to detect count of processor cores automatically. Something like this:

$pool = new Pool(get_processor_cores_number(), 'WebWorker');

How is it possible with PHP?

Upvotes: 16

Views: 9649

Answers (6)

Matt B.
Matt B.

Reputation: 91

Avoid spinning up a whole new shell to get simple information out of the OS when you can. This is extremely slow and is a memory hog as you're spawning an entire command interpreter for a single simple task.

Here is a quick function to do it on Linux or Windows that doesn't require spawning a whole new shell:

function get_total_cpu_cores() {
    return (int) (PHP_OS_FAMILY === 'Windows'
        ? getenv("NUMBER_OF_PROCESSORS")
        : substr_count(file_get_contents("/proc/cpuinfo"), "processor"));
}

This will work on any semi-modern windows installation (since at LEAST Windows 95) and will work on most, if not all, flavors of Linux assuming you have the rights to read /proc/cpuinfo. But most installations make that world readable... so shouldn't have any problems.

Further note to bear in mind technically this is showing you the CPU cores available as the OS sees it. Both Windows and Linux see hyperthreaded CPU threads as cores even though they aren't physical cores. That said, this should still work for what you're trying to do unless you REALLY need to know the number of physical cores on a machine. Then you're in for a more involved process.

Hope this helps!

Upvotes: 5

Harry
Harry

Reputation: 289

In case anyone looking for a easy function to get total CPU cores for Windows and Linux both OS.

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;
}

Upvotes: 9

inquam
inquam

Reputation: 12942

In my own library, I have a function for this among other things. You can easily modify it where it uses nonstandard PHP functions.

For instance, I cache the result so you can ignore that. Then I have functions to check if we are running on Linux, Mac or Windows. You could insert a similar check of your own there. For executing the actual system specific check I use my own Process class which allows things such as reconnecting to running processes on subsequent requests to check status, output etc. But you can change that and just use 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;
}

Upvotes: 2

teknoraver
teknoraver

Reputation: 936

If the server is a Linux machine you can do it with the following snippet:

$ncpu = 1;

if(is_file('/proc/cpuinfo')) {
    $cpuinfo = file_get_contents('/proc/cpuinfo');
    preg_match_all('/^processor/m', $cpuinfo, $matches);
    $ncpu = count($matches[0]);
}

Upvotes: 15

Joe Watkins
Joe Watkins

Reputation: 17168

Here is an extension exposing sysconf: krakjoe/sysconf

<?php
$cpusConfigured = sysconf(SYSCONF_NPROCESSORS_CONF);
$cpusOnline     = sysconf(SYSCONF_NPROCESSORS_ONLN);
?>

Most applications only care about the number configured.

Upvotes: 5

olibiaz
olibiaz

Reputation: 2595

You can do something like that, of course your server should be in linux:

function get_processor_cores_number() {
    $command = "cat /proc/cpuinfo | grep processor | wc -l";

    return  (int) shell_exec($command);
}

You will execute a shell command then cast it to int.

Upvotes: 7

Related Questions