Easy way of counting # processeses running?

  • Context:
  • Thread starter Thread starter ORF
  • Start date Start date
  • Tags Tags
    Counting Running
Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
6 replies · 2K views
ORF
Messages
169
Reaction score
19
hello

I needed to count the number of processes (with the same name). I found that this bash script works,
Code:
#!/bin/bash
exit $(ps cax | grep firefox | wc -l);

and the exit value can be caught by this code
Code:
#include <stdlib.h>   // sytem
#include <iostream> // std::cout, std::endl

int main()
{
  int ret = system("./myBashScript.sh 2>&1 > /dev/null");
  std::cerr << "Number of firefox sessions: " << WEXITSTATUS(ret) << std::endl;
  return 0;
}

This way is dirty and limited to linux.

Can this job be done by a C/C++ routine, non-OS dependent? Or at least, can this job avoid calling "ps cax | grep firefox | wc -l" as an external bash script?

Thank you for your time.

Regards,
ORF
 
on Phys.org
Using the snippet from https://stackoverflow.com/questions...nd-get-output-of-command-within-c-using-posix and adapting it to your particular question, an answer to "or at least ..." could be

Code:
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>

std::string exec(const char* cmd) {
    std::array<char, 128> buffer;
    std::string result;
    std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
    if (!pipe) throw std::runtime_error("popen() failed!");
    while (!feof(pipe.get())) {
        if (fgets(buffer.data(), 128, pipe.get()) != nullptr) {
            result += buffer.data();
   }
    }
    return result;
}

int main()
{
  const std::string result = exec("ps cax | grep firefox | wc -l");
  const int nSessions = std::stoi(result);
  std::cerr << "Number of firefox sessions: " << nSessions << std::endl;
  return 0;
}
(I used the c++11 version and changed "std::nullptr" to "nullptr". In the unlikely case your compiler does not support c++11 the stackoverflow page also has a function using older c++ versions).
 
WWGD said:
EDIT What system do you have? In Windows you just go to the Task Manager, " For the rest of us".
My sense is that OP wants to count processes programmatically.
 
ORF said:
Can this job be done by a C/C++ routine, non-OS dependent?
No.
Wait... are you sure that you're doing it right? system() returns the exit code of your script (which should be 0.) You want to get stdout. For this, I recommend using popen(), fgets(), and pclose().

If you want something platform independent, then you need to write something for it:
Code:
class Process {
public:
   std::string run(const std::string & cmd){
      //everything below is pseudocode
      #ifdef WIN32
            CreatePipe(&read, &write, &attr, 0);
            CreateProcessA(cmd);
            WaitForSingleObject();
      #else
            pipe = popen(cmd);
            fgets loop;
            pclose(pipe);
      #endif
   }
}
 
Hello

Mark44 said:
My sense is that OP wants to count processes programmatically.
Yes, that would be the idea

newjerseyrunner said:
Wait... are you sure that you're doing it right? system() returns the exit code of your script (which should be 0.)
It was a dirty way... the returned value is 0, but you can catch the number of processes using WEXITSTATUS.

Thank you all: the popen/pclose was the proper way of doing it.

Regards!
 
  • Like
Likes   Reactions: newjerseyrunner
It is called system programming. Basically you go into kernel mode(windows and linux/unix) and enumerate a data structure called the process_masthead.
Being realistic, I am sure you do not want to do this. For example do you know the system apis and functions involved?
https://blog.codinghorror.com/understanding-user-and-kernel-mode/ Windows only. Unsurprisingly, linux is different. It has kernel mode as well, just to be clear.

As a practical answer, I would go to the GNU (gnu herd) site or the linux kernel site and download the code and spend a month or so learning it. I did this for Solaris 8 long ago and it was very enlightening. The alternative: use system code already in place. sysinternals has good code you can call for all of your system needs on windows -- using the system() method.

https://www.sysinternals.com which is now part of MS technet, some of their process enumeration code was there last time I looked. They have really great standalone executables.