讓多核CPU佔用率曲線聽你指揮(Linux實現)——《編程之美》1.1繼續學習

來源:互聯網
上載者:User

本回將嘗試在Linux環境下能否在系統監視器中畫出一個正弦曲線。本人環境為Ubuntu 11.04.

基本思想還是和Windows下面的相同,更換系統調用,便可以實現功能的遷移。

#include <time.h>#include <sys/time.h>#include <unistd.h>#include<stdlib.h>#include<math.h>#define DWORD unsigned long#define UINT64 unsigned long longconst double SPLIT = 0.01;const int COUNT = 200;const double PI = 3.14159265;const int INTERVAL = 300;int main(int argc, char* argv[] ){struct timeval tms;DWORD busySpan[COUNT];DWORD idleSpan[COUNT];int half = INTERVAL/2, i;double radian = 0.0;for(i = 0; i < COUNT; ++i){busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));idleSpan[i] = INTERVAL - busySpan[i];radian += SPLIT;}clock_t startTime = 0;int j = 0;while(1){j = j % COUNT;timerclear(&tms);gettimeofday(&tms,NULL);UINT64 startTime = tms.tv_usec;while(1)//clock返回該進程從啟動到現在經曆的毫秒數(千分之一秒){timerclear(&tms);gettimeofday(&tms,NULL);UINT64 nowTime = tms.tv_usec;if((nowTime - startTime)/1000 > busySpan[j])break;}        if(usleep(idleSpan[j]*1000))  //精確到微秒(百萬分之一秒)的函數           exit(-1);j++;}return 0;}

gettimeofday()函數用來取得目前時間(微秒,百萬分之一秒)。並通過參數傳遞給結構體timeval類型的tms。

int gettimeofday(struct timeval *tv, struct timezone *tz);

tz用來擷取時區資訊。不做介紹。

結構體timeval的定義為:

struct timeval

{

         time_t                tv_sec;            //seconds

         suseconds_t    tv_usec;         //microseconds

};

tz如果是NULL的話將不傳遞時區資訊。tv提供秒為單位的和微妙為單位的從Epoch開始的計數。

結構體timeval的域為類型long的域。

此函數返回0,表示成功,-1表示失敗。

 

Windows中,GetTickCount返回的是從系統啟動到現在的毫秒。

int usleep(useconds_t usec);

定義在標頭檔unistd.h中。它使當前進程掛起至少usec微秒(百萬分之一秒).睡眠時間可能會被任意系統活動或進程切換開銷或系統計時器的精確度而輕微延遲。成功時返回0,錯誤時返回-1.

 

或者使用clock()來得到系統時間也是可以的。它返回從進程啟動到現在經曆的時間,單位是毫秒(千分之一秒)。定義在標頭檔time.h下.

           clock_t clock(void);

相應代碼如下。


 

#include <time.h>#include <sys/time.h>#include <unistd.h>#include<stdlib.h>#include<math.h>#define DWORD unsigned long#define UINT64 unsigned long longconst double SPLIT = 0.01;const int COUNT = 200;const double PI = 3.14159265;const int INTERVAL = 300;int main(int argc, char* argv[] ){struct timeval tms;DWORD busySpan[COUNT];DWORD idleSpan[COUNT];int half = INTERVAL/2, i;double radian = 0.0;for(i = 0; i < COUNT; ++i){busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));idleSpan[i] = INTERVAL - busySpan[i];radian += SPLIT;}clock_t startTime = 0;int j = 0;while(1){j = j % COUNT;timerclear(&tms);gettimeofday(&tms,NULL);clock_t startTime = clock();while((clock()-startTime) <= busySpan[j])//clock返回該進程從啟動到現在經曆的毫秒數(千分之一秒);        if(usleep(idleSpan[j]*1000))  //精確到微秒(百萬分之一秒)的函數           exit(-1);j++;}return 0;}

但對於多核CPU,如何限制進程在一個CPU上運行呢?

 

如何察看某個進程在哪個CPU上運行:

在控制台中輸入:

#top -d 1

之後按下f.進入top Current Fields設定頁面:

選中:j: P          = Last used cpu (SMP)

則多了一項:P 顯示此進程使用哪個CPU。

 

經過實驗發現:同一個進程,在不同時刻,會使用不同CPU Core.這應該是Linux Kernel SMP處理的。

 

 

本程式通過這個方法查看,將會在多個CPU上運行。

想要讓它在一個CPU上執行,可以這樣做:

          1.下載包schedtool.

                    在控制台中輸入:sudo apt-get install schedtool,然後輸入你的密碼。

schedtool是Linux下用來查詢或設定CPU狀態的工具。通過不同的參數可以查看或設定不同的屬性。

[-0|-N] [-1|-F] [-2|-R] [-3|-B] [-4|-I] [-5|-D]        [-M policy]        [-a affinity]        [-p prio]        [-n nice_level]        [-e command [arg ...]]        [-r]        [-v]        [-h

我們這裡要用到的是 -a和-e。其他可以參考這裡:

http://linux.die.net/man/8/schedtool

-a用來設定進程在哪個CPU上運行。-a的參數為:

0x1  表示只運行在CPU0(00000001)

0x2 表示只運行在CPU1(00000010)

0x4表示紫雲行在CPU2(00000100)

0x8表示只運行在CPU3(00001000)

etc.

或者,多CPU運行可以這樣表示,

0x7表示可以運行在CPU0,1,2  (00000111)

0x5表示可運行在CPU0,2     (00000101)

以此類推。

-e用來通過指定的參數來執行命令。後面的參數為控制台命令。

 

在Linux下,如何確認是多核或多CPU:

#cat /proc/cpuinfo

如果有多個類似以下的項目,則為多核或多CPU:

processor       : 0

......

processor       : 1

 

在編譯後,我們執行命令:sched -a 0x1 -e ./案頭/sin

可以通過上面介紹的方法查看進程sin是否在同一個CPU上運行。

然後就可以通過系統監視器查看運行結果啦!

運行結果(橙色線):

還有一段Python的代碼,運行是與上面類似的,這個來自於網上^_^:

#!/usr/bin/env pythonimport itertools, math, time, systime_period = float(sys.argv[1]) if len(sys.argv) > 1 else 30   # secondstime_slice  = float(sys.argv[2]) if len(sys.argv) > 2 else 0.04 # secondsN = int(time_period / time_slice)for i in itertools.cycle(range(N)):    busy_time = time_slice / 2 * (math.sin(2*math.pi*i/N) + 1)    t = time.clock() + busy_time    while t > time.clock():        pass    time.sleep(time_slice - busy_time);

在控制台下輸入命令:sched -a 0x1 -e python ./案頭/sin_p.py(此處寫你源檔案的路徑).即可!

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.