সি থেকে লিনাক্সে পিআইডি দ্বারা কোনও প্রক্রিয়ার সিপিইউ ব্যবহারের গণনা কীভাবে করা যায়?


95

আমি লিনাক্সে প্রদত্ত প্রক্রিয়া আইডির জন্য প্রোগ্রাম্যিকভাবে [সি তে] সিপিইউ ব্যবহার% গণনা করতে চাই।

প্রদত্ত প্রক্রিয়াটির জন্য আমরা কীভাবে রিয়েলটাইম সিপিইউ ব্যবহার করতে পারি?

এটি আরও পরিষ্কার করার জন্য:

  • প্রদত্ত প্রসেসিড বা প্রক্রিয়াটির জন্য আমার সিপিইউ ব্যবহার নির্ধারণ করতে সক্ষম হওয়া উচিত।
  • প্রক্রিয়াটি শিশু প্রক্রিয়া হওয়ার দরকার নেই।
  • আমি সমাধান 'সি' ভাষায় চাই।

শীর্ষের আউটপুট ধরার বিষয়ে কী বলা যায়?
ডুসফট

দক্ষ করার জন্য এটি সর্বোত্তম উপায় নয়; y
কোডিংফ্রেক

'শীর্ষ' শুরু করতে সম্ভবত একটি "ব্যয়বহুল" সিস্টেম কল প্রয়োজন হবে।
লিরান ওরেভি

@ লিরান: ঠিক বলেছেন :)
vpram86

জিনিসগুলি করার এই
পদ্ধতিটি

উত্তর:


153

আপনাকে এ থেকে ডেটা বিশ্লেষণ করতে হবে /proc/<PID>/stat। এগুলি প্রথম কয়েকটি ক্ষেত্র ( Documentation/filesystems/proc.txtআপনার কার্নেলের উত্স থেকে):

Table 1-3: Contents of the stat files (as of 2.6.22-rc3)
..............................................................................
 Field          Content
  pid           process id
  tcomm         filename of the executable
  state         state (R is running, S is sleeping, D is sleeping in an
                uninterruptible wait, Z is zombie, T is traced or stopped)
  ppid          process id of the parent process
  pgrp          pgrp of the process
  sid           session id
  tty_nr        tty the process uses
  tty_pgrp      pgrp of the tty
  flags         task flags
  min_flt       number of minor faults
  cmin_flt      number of minor faults with child's
  maj_flt       number of major faults
  cmaj_flt      number of major faults with child's
  utime         user mode jiffies
  stime         kernel mode jiffies
  cutime        user mode jiffies with child's
  cstime        kernel mode jiffies with child's

আপনি সম্ভবত পরে utimeএবং / বা stime। আপনাকে cpuএখান থেকে লাইনটি পড়তে হবে /proc/statযা দেখতে মনে হচ্ছে:

cpu  192369 7119 480152 122044337 14142 9937 26747 0 0

এটি আপনাকে জিফির ইউনিটগুলিতে বিভিন্ন বিভাগে ব্যবহার করা হয়েছে এমন সংযোজিত সিপিইউ সময় বলে। একটি time_totalপরিমাপ পেতে আপনাকে এই লাইনের মানগুলির যোগফল নেওয়া দরকার ।

উভয় পড়ুন utimeএবং stimeপ্রক্রিয়ার জন্য আপনি আগ্রহী করছি, এবং পড়া time_totalথেকে /proc/stat। তারপরে এক সেকেন্ডের জন্য ঘুমোও এবং সেগুলি আবার পড়। আপনি এখন স্যাম্পলিংয়ের সময় প্রক্রিয়াটির সিপিইউ ব্যবহার গণনা করতে পারেন:

user_util = 100 * (utime_after - utime_before) / (time_total_after - time_total_before);
sys_util = 100 * (stime_after - stime_before) / (time_total_after - time_total_before);

ধারণা তৈরী কর?


12
একটি "জিফ্ফাই" সিপিইউ সময়ের একক। দেওয়াল-ঘড়ির সময় যা ঠিক তার সাথে কী মিলছে তা নির্ভর করে আর্কিটেকচার এবং আপনার কার্নেলটি কীভাবে কনফিগার করা হয়েছে তার উপর নির্ভর করে তবে গুরুত্বপূর্ণ বিষয়টি /proc/statআপনাকে সিপিইউ মোট কতগুলি জিফি কার্যকর করেছে এবং /proc/<PID>/statআপনাকে বলে যে কতগুলি জিফিকে মৃত্যুদন্ড কার্যকর করা হয়েছিল একক প্রক্রিয়া
ক্যাফে

4
@ অ্যাডভোকট: এটি একটি সিউডো-ফাইল যা কার্নেল থেকে প্রক্রিয়া প্রয়োগের পরিসংখ্যানগুলি পুনরুদ্ধার করতে একটি ইন্টারফেস প্রয়োগ করে।
ক্যাফে

4
ক্ষেত্রগুলি সম্পর্কে আরও তথ্যের man proc/proc/[pid]/stat
সন্ধানকারী লোকদের

4
Zizzu (নীচে) সরবরাহিত একটির সাথে ক্যাফের সমাধানটির তুলনা করে, ক্যাফের সমাধানটি সিস্টেম এবং ব্যবহারকারীকে পৃথক পৃথক সময় দেয় তবে সিপিইউগুলির সংখ্যার সাথে এই মানগুলির কোনওটিরই গুণ হয় না। এটা করা উচিত নয়?
লিনাক্সফান

4
স্পষ্টতই ওপি দ্বিমত পোষণ করেছে। কী অন্তর্দৃষ্টি এখানে ব্যবহার করা /procসিউডো-ফাইল সিস্টেম: মত প্রমিত C ফাইল সিস্টেম এক্সেস ফাংশন শিক্ষার fopen()এবং scanf()বিন্দু পাগল হয়ে গেছেন।
ক্যাফে

11

getrusage () আপনাকে বর্তমান প্রক্রিয়া বা এর সন্তানের ব্যবহার নির্ধারণে সহায়তা করতে পারে

আপডেট: আমি কোনও এপিআই মনে করতে পারি না। তবে সমস্ত বিশদ / প্রোক / পিআইডি / স্ট্যাটে থাকবে, সুতরাং আমরা যদি এটির বিশ্লেষণ করতে পারি তবে আমরা শতাংশ পেতে পারি।

সম্পাদনা: যেহেতু সিপিইউ% গণনা করার জন্য সরাসরি এগিয়ে নেই, আপনি এখানে নমুনা ধরণের স্টাফ ব্যবহার করতে পারেন। একটি পয়েন্টে পিআইডি-র জন্য সিটিটাইম এবং ইউটাইম পড়ুন এবং 1 সেকেন্ডের পরে আবার একই মানগুলি পড়ুন। পার্থক্যটি এবং শতকে ভাগ করে নিন। আপনি গত এক সেকেন্ডের জন্য সেই প্রক্রিয়াটির জন্য ব্যবহার পাবেন।

(অনেক প্রসেসর থাকলে আরও জটিল হয়ে উঠতে পারে)


4
কীভাবে getrusage () সিস্টেম কল আমাকে কোনও প্রক্রিয়ার সিপিইউ ব্যবহার গণনা করতে সহায়তা করে ??
কোডিংফ্রেয়াক

@ কোডিংফ্রোক আমি প্রশ্নটি ভুল বুঝেছি। এখন আপনি এটি আপডেট করার পরে, পরিষ্কার।
vpram86

4
@ অ্যাভিয়েটার সিপিইউ% = (প্রসেসুসারটাইম + প্রসেসার্নালটাইম) / (সিপিইউসারটাইম + সিপিইউকার্নালটাইম) কীভাবে আমি "প্রসেসুসারটাইম" এবং এর জন্য মান পেতে পারি। ??? আমি "/ proc / পিআইডি / স্ট্যাট" ফাইলটিতে বিভিন্ন মান দেখতে পাই। কোনটি কোনটির সাথে মিলিত হয় কোনটি ??
কোডিংফ্রেয়াক

@ কোডিংফ্রোক: সিপিইউ সময় গণনা করা কঠিন। আমার অনুমান করা সমস্ত পিআইডি পরিসংখ্যানগুলির মধ্যে আপনাকে লুপ করা দরকার (যদিও নিশ্চিত নয়)
vpram86

@ এভিয়েটর এর কিছু উপায় বা অন্য উপায় হতে পারে ... যেহেতু শীর্ষের মতো অ্যাপ্লিকেশনগুলিও তাদের আউটপুট দেখানোর জন্য সিপিইউ ব্যবহার গণনা করতে পারে
কোডিংফ্রেক

7

আমার মতো নতুনদের জন্য পদক্ষেপের সহজ পদক্ষেপ:

  1. /proc/statপেতে প্রথম লাইন পড়ুন total_cpu_usage1
    sscanf(line,"%*s %llu %llu %llu %llu",&user,&nice,&system,&idle);
    total_cpu_usage1 = user + nice + system + idle;
  1. আপনি সিপিইউ ব্যবহারটি জানতে চান এমন প্রক্রিয়ার পিআইডি /proc/pid/statকোথায় রয়েছে pidতা পড়ুন :
    sscanf(line,
    "%*d %*s %*c %*d" //pid,command,state,ppid

    "%*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu"

    "%lu %lu" //usertime,systemtime

    "%*ld %*ld %*ld %*ld %*ld %*ld %*llu"

    "%*lu", //virtual memory size in bytes
    ....)
  1. এখন যোগফল usertimeএবং systemtimeএবং পেতেproc_times1
  2. এখন 1 সেকেন্ড বা আরও অপেক্ষা করুন
  3. আবার এটি করুন, এবং পেতে total_cpu_usage2এবংproc_times2

সূত্রটি হ'ল:

(number of processors) * (proc_times2 - proc_times1) * 100 / (float) (total_cpu_usage2 - total_cpu_usage1)

আপনি সিপিইউর পরিমাণটি পেতে পারেন /proc/cpuinfo


4
আপনার সমাধানটি ভাল তবে সিপিইউগুলির সংখ্যা পেতে এটি আরও সহজ করুন make এই লোকটিকে অন্তর্ভুক্ত করুন #include <unistd.h>এবং এই পদ্ধতিটি কল করুনint nb = sysconf(_SC_NPROCESSORS_ONLN);
ডেভিড গায়ন

4
আমি বুঝতে পারছি না কেন (প্রসেসরের সংখ্যা) দ্বারা গুণন করুন, ডেল্টা (প্র্যাক_টাইমস) ধরে নেওয়া হয় যে এটি যে कोरটির উপর কার্যকর হয়েছিল। ফ্যাক্টর বা সিপিইউ দ্বারা গুণ না করে এটি সঠিক হওয়া উচিত।
জয়বলানআরন

5

আমি একটি প্রসেসের ব্যবহারকারী + কার্নেল সিপিইউ ব্যবহার গণনা করতে ক্যাফ উত্তরের উপর ভিত্তি করে দুটি ছোট সি ফাংশন লিখেছি: https://github.com/fho/code_snippets/blob/master/c/getusage.c


এটির সংকলিত সংস্করণ কি আছে যা এটি সংকলনের সময় আমাকে ত্রুটি দেয় এবং আমি কীভাবে এটি ব্যবহার করতে পারি?
মেঘাট

আমার একটি প্রধান () ফাংশন নেই তাই এটি আপনি সংকলন ও সম্পাদন করতে পারেন তার চেয়ে "স্ট্যান্ডেলোন" প্রোগ্রাম নয়। আপনাকে একটি মূল () ফাংশন লিখতে হবে যা getusage.c এর ক্রিয়াকলাপের সাথে কিছু কাজ করে
fho

এটি আসলে সি ফাংশন ব্যবহার করে না। কমান্ড আউটপুট পার্স করার জন্য কেবল একটি স্বেচ্ছাসেবী ভাষা ব্যবহার করা।
গ্রাহাম

4

আপনি আরও বিশদে বিশদটির জন্য ম্যানপেজটি পড়তে পারেন , তবে সংক্ষেপে আপনি কোনও প্রক্রিয়া সম্পর্কে তথ্য পেতে / proc / [সংখ্যা] / স্টেট পড়তে পারেন। এটি 'ps' কমান্ড দ্বারাও ব্যবহৃত হয়।

সমস্ত ক্ষেত্র এবং তাদের স্ক্যানফ ফর্ম্যাট স্পেসিফায়ারগুলি প্রো ম্যানপ্যাগ ই- তে নথিভুক্ত ।

ম্যানপেজ থেকে অনুলিপি করা কিছু তথ্য এখানে দেওয়া হয়েছে (এটি বেশ দীর্ঘ)

          pid %d The process ID.

          comm %s
                 The  filename of the executable, in parentheses.  This is
                 visible whether or not the executable is swapped out.

          state %c
                 One character from the string "RSDZTW" where  R  is  runâ
                 ning,  S is sleeping in an interruptible wait, D is waitâ
                 ing in uninterruptible disk sleep,  Z  is  zombie,  T  is
                 traced or stopped (on a signal), and W is paging.

          ppid %d
                 The PID of the parent.

          pgrp %d
                 The process group ID of the process.

          session %d
                 The session ID of the process.

          tty_nr %d
                 The tty the process uses.

          tpgid %d
                 The  process group ID of the process which currently owns
                 the tty that the process is connected to.

"সিপিইউ ব্যবহার" এবং "বর্তমান অবস্থা" অবস্থান এবং গতির মতো। আপনি যদি একজনকে জানেন তবে আপনি অন্যটিকে জানতে পারবেন না। সিপিইউর ব্যবহার একটি সময়কালের উপর নির্ভর করে তাই আপনার প্রক্রিয়াটি কতবার "আর" অবস্থায় থাকে তা আপনাকে নিজেরাই পরীক্ষা করতে হবে।
বোম্বে

হুঁ, ভাল প্রশ্ন, আমি সবসময় কেবল ধরেই নিয়েছিলাম এটি সেখানেই থাকবে! সম্ভবত আপনি এই ভেরিয়েবলগুলি থেকে এটি গণনা করতে সক্ষম হবেন
আন্দ্রে মিলার

আপনি যদি শীর্ষ কমান্ডের আউটপুট চেক করেন তবে আপনি সিপিইউ ব্যবহার দেখতে পাবেন .... তবে আমি সিপিইউ ব্যবহার গণনা করতে শীর্ষ আউটপুটটি দিয়ে গ্রেপিংয়ে আগ্রহী নই .....
কোডিংফ্রোক

@ কোডিংফ্রোক: ps auxআরও ভাল :)
vpram86

@ অ্যাভিয়েটার - আমি ইতিমধ্যে আপনাকে সিপিইউ ব্যবহারের জন্য% শেল কমান্ডের আউটপুট গ্রেপিং সম্পর্কে ভুলে যেতে বলেছি USAGE%
কোডিংফ্রেক

2

"পিডস্ট্যাট" কমান্ডটি একবার দেখুন, আপনার যা প্রয়োজন ঠিক তা মনে হচ্ছে।


@ জেমস - আমি আমার ফেডোরা 9 মেশিনে পিডস্ট্যাট কমান্ডটি অ্যাক্সেস করতে পারছি না।
কোডিংফ্রেক

@ কোডিংফ্রোক - আপনার এটির জন্য সিস্টেস্ট্যাট সরঞ্জাম ইনস্টল করতে হবে
চিন্তন

2

এটি আমার সমাধান ...

/*
this program is looking for CPU,Memory,Procs also u can look glibtop header there was a lot of usefull function have fun..
systeminfo.c
*/
#include <stdio.h>
#include <glibtop.h>
#include <glibtop/cpu.h>
#include <glibtop/mem.h>
#include <glibtop/proclist.h>



int main(){

glibtop_init();

glibtop_cpu cpu;
glibtop_mem memory;
glibtop_proclist proclist;

glibtop_get_cpu (&cpu);
glibtop_get_mem(&memory);


printf("CPU TYPE INFORMATIONS \n\n"
"Cpu Total : %ld \n"
"Cpu User : %ld \n"
"Cpu Nice : %ld \n"
"Cpu Sys : %ld \n"
"Cpu Idle : %ld \n"
"Cpu Frequences : %ld \n",
(unsigned long)cpu.total,
(unsigned long)cpu.user,
(unsigned long)cpu.nice,
(unsigned long)cpu.sys,
(unsigned long)cpu.idle,
(unsigned long)cpu.frequency);

printf("\nMEMORY USING\n\n"
"Memory Total : %ld MB\n"
"Memory Used : %ld MB\n"
"Memory Free : %ld MB\n"
"Memory Buffered : %ld MB\n"
"Memory Cached : %ld MB\n"
"Memory user : %ld MB\n"
"Memory Locked : %ld MB\n",
(unsigned long)memory.total/(1024*1024),
(unsigned long)memory.used/(1024*1024),
(unsigned long)memory.free/(1024*1024),
(unsigned long)memory.shared/(1024*1024),
(unsigned long)memory.buffer/(1024*1024),
(unsigned long)memory.cached/(1024*1024),
(unsigned long)memory.user/(1024*1024),
(unsigned long)memory.locked/(1024*1024));

int which,arg;
glibtop_get_proclist(&proclist,which,arg);
printf("%ld\n%ld\n%ld\n",
(unsigned long)proclist.number,
(unsigned long)proclist.total,
(unsigned long)proclist.size);
return 0;
}

makefile is
CC=gcc
CFLAGS=-Wall -g
CLIBS=-lgtop-2.0 -lgtop_sysdeps-2.0 -lgtop_common-2.0

cpuinfo:cpu.c
$(CC) $(CFLAGS) systeminfo.c -o systeminfo $(CLIBS)
clean:
rm -f systeminfo

4
লাইবটপ লাইব্রেরির সাহায্য ব্যবহার করে মনে হচ্ছে ..?
কোডিংফ্রেইক

4
আমি এটি পছন্দ করি - গ্রন্থাগারটি সোজা। আমি অবাক হই যে মোট ব্যবহারের মোট ক্ষমতার কত% দেখার উপায় আছে?
Cera

1

আপনি যখন নিরীক্ষণ নির্দিষ্ট প্রক্রিয়া চান, সাধারণত এটি স্ক্রিপ্টিং দ্বারা সম্পন্ন করা হয়। এখানে পার্ল উদাহরণ। এটি শীর্ষের মতো একই উপায়ে পার্সেন্টগুলি রাখে, এটি একটি সিপিইউতে স্কেল করে। তারপরে যখন কিছু প্রক্রিয়া 2 টি থ্রেড সহ সক্রিয় থাকে, তখন সিপিইউ ব্যবহার 100% এর বেশি হতে পারে। বিশেষভাবে দেখুন কীভাবে সিপু কোরগুলি গণনা করা হয়: ডি তবে আমাকে আমার উদাহরণটি দেখান:

#!/usr/bin/perl

my $pid=1234; #insert here monitored process PID

#returns current process time counters or single undef if unavailable
#returns:  1. process counter  , 2. system counter , 3. total system cpu cores
sub GetCurrentLoads {
    my $pid=shift;
    my $fh;
    my $line;
    open $fh,'<',"/proc/$pid/stat" or return undef;
    $line=<$fh>;
    close $fh;
    return undef unless $line=~/^\d+ \([^)]+\) \S \d+ \d+ \d+ \d+ -?\d+ \d+ \d+ \d+ \d+ \d+ (\d+) (\d+)/;
    my $TimeApp=$1+$2;
    my $TimeSystem=0;
    my $CpuCount=0;
    open $fh,'<',"/proc/stat" or return undef;
    while (defined($line=<$fh>)) {
        if ($line=~/^cpu\s/) {
            foreach my $nr ($line=~/\d+/g) { $TimeSystem+=$nr; };
            next;
        };
        $CpuCount++ if $line=~/^cpu\d/;
    }
    close $fh;
    return undef if $TimeSystem==0;
    return $TimeApp,$TimeSystem,$CpuCount;
}

my ($currApp,$currSys,$lastApp,$lastSys,$cores);
while () {
    ($currApp,$currSys,$cores)=GetCurrentLoads($pid);
    printf "Load is: %5.1f\%\n",($currApp-$lastApp)/($currSys-$lastSys)*$cores*100 if defined $currApp and defined $lastApp and defined $currSys and defined $lastSys;
    ($lastApp,$lastSys)=($currApp,$currSys);
    sleep 1;
}

আমি আশা করি এটি যে কোনও পর্যবেক্ষণে আপনাকে সহায়তা করবে। অবশ্যই আমি সি উত্সে ব্যবহার করেছি এমন পার্ল রেজেক্সপগুলি রূপান্তর করার জন্য আপনার স্ক্যানফ বা অন্যান্য সি ফাংশন ব্যবহার করা উচিত। অবশ্যই ঘুমানোর জন্য 1 সেকেন্ড বাধ্যতামূলক নয়। আপনি যে কোন সময় ব্যবহার করতে পারেন। প্রভাবটি হ'ল, আপনি নির্দিষ্ট সময়ের মধ্যে অ্যাভারেজ লোড পাবেন। আপনি যখন এটি পর্যবেক্ষণের জন্য ব্যবহার করবেন, অবশ্যই সর্বশেষ মানগুলি আপনার বাইরে রাখা উচিত। এটি প্রয়োজন, কারণ পর্যবেক্ষণ সাধারণত পর্যায়ক্রমে স্ক্রিপ্টগুলিতে কল করে এবং স্ক্রিপ্টটি তার কাজটি যথাযথভাবে শেষ করতে পারে।



0

আমি মনে করি এটি জিএনইউ "সময়" কমান্ড উত্স কোডটি দেখার মতো। সময় এটি বাস্তব সময় অতিবাহিত সময়ের সাথে ব্যবহারকারী / সিস্টেম সিপিইউ সময়কে আউটপুট করে। এটি ওয়েট 3 / ওয়েট 4 সিস্টেম কল (যদি উপলভ্য থাকে) কল করে এবং অন্যথায় এটি টাইম সিস্টেম কলকে কল করে। অপেক্ষা করুন * সিস্টেম কল একটি "rusage" স্ট্রাক্ট ভেরিয়েবল এবং বার কল কল "টিএমএস" দেয়। এছাড়াও, আপনি গেট্রাসেজ সিস্টেম কলটি দেখে নিতে পারেন যা খুব আকর্ষণীয় সময় সম্পর্কিত তথ্যও দেয়। সময়


জিএনইউ "সময়" কেবল "সময়" এর শিশু প্রক্রিয়াটির জন্য
গ্রাহাম

0

প্রোক থেকে এটি পার্সিংয়ের পরিবর্তে, কেউ সিপিইউতে ব্যবহৃত প্রক্রিয়া / থ্রেড অনুপাত বা প্রাচীরের ঘড়ির সময় এবং সময় হিসাবে সিপিইউ ব্যবহার গণনা করতে পারে (যেমন) বা ক্লক_জেটটাইম () functions


গেরুসেজ ক্লক_জেটটাইম সীমাবদ্ধ, সমস্ত প্রক্রিয়া নয়
গ্রাহাম

0

স্ট্রেস ব্যবহার করে সিপিইউ ব্যবহারের সময়কাল ধরে গণনা করা দরকার:

# top -b -n 1 -p 3889
top - 16:46:37 up  1:04,  3 users,  load average: 0.00, 0.01, 0.02
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  5594496 total,  5158284 free,   232132 used,   204080 buff/cache
KiB Swap:  3309564 total,  3309564 free,        0 used.  5113756 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 3889 root      20   0  162016   2220   1544 S   0.0  0.0   0:05.77 top
# strace top -b -n 1 -p 3889
.
.
.
stat("/proc/3889", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/3889/stat", O_RDONLY)       = 7
read(7, "3889 (top) S 3854 3889 3854 3481"..., 1024) = 342
.
.
.

nanosleep({0, 150000000}, NULL)         = 0
.
.
.
stat("/proc/3889", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/3889/stat", O_RDONLY)       = 7
read(7, "3889 (top) S 3854 3889 3854 3481"..., 1024) = 342
.
.
.
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.