一、實驗目的
設計並實現Unix的“time”命令。“mytime”命令通過命令行參數接受要運行的程序,創建一個獨立的進程來運行該程序,並記錄程序運行的時間。
二、實驗內容
在Windows下實現:
- 使用CreateProcess()來創建進程
- 使用WaitForSingleObject()在“mytime”命令和新創建的進程之間同步
- 調用GetSystemTime()來獲取時間
在Linux下實現:
- 使用fork()/execv()來創建進程運行程序
- 使用wait()等待新創建的進程結束
- 調用gettimeofday()來獲取時間
三、實驗環境
windows 7和ubuntu 10.10
四、程序設計與實現
主要API函數說明:
windows:
BOOL CreateProcess
(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes。
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
linux:
int execv(char *pathname, char *argv[]);
這次實驗不論是linux還是windows,主要思路只有一個利用fork或者createprocess建立一個子進程,在建立成功之後記錄運行時間,然後利用wait或者waitforsingleobject函數等待子進程的同步,之後再記錄運行時間,用兩次時間相減即可。
這裏值得說明的是,要求中windows下的計時函數GetSystemTime()不太好用了,函數返回的是系統的時間,我們要用兩次時間相減,這裏還要考慮到有負數的情況,所以還要考慮借位,其實windows下面有一個好用的函數clock(),這個函數對於計時很在行。
window:
- #include <iostream>
- #include<windows.h>
- using namespace std;
- int main(int argc,char **argv)
- {
- int year,month,day,hour,minutes,seconds,milliseconds;
- SYSTEMTIME start,end;
- STARTUPINFO si; //一些必備參數設置
- memset(&si, 0, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = SW_SHOW;
- PROCESS_INFORMATION pi; //必備參數設置結束
- if(!CreateProcess(argv[1],NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
- {
- cout<<"Create Fail!"<<endl;
- exit(1);
- }
- else
- {
- GetSystemTime(&start);
- cout<<"Success!"<<endl;
- }
- WaitForSingleObject(pi.hProcess,INFINITE);
- GetSystemTime(&end);
- milliseconds=end.wMilliseconds-start.wMilliseconds;
- seconds=end.wSecond-start.wSecond;
- minutes=end.wMinute-start.wMinute;
- hour=end.wHour-start.wHour;
- day=end.wDay-start.wDay;
- month=end.wMonth-start.wMonth;
- year=end.wYear-start.wYear;
- if ( milliseconds < 0)
- {
- seconds--;
- milliseconds+=1000;
- }
- if ( seconds < 0 )
- {
- minutes--;
- seconds+=60;
- }
- if ( hour < 0 )
- {
- day--;
- hour+=24;
- }
- if ( day < 0 )
- {
- month--;
- day+=30;
- }
- if ( month < 0 )
- {
- year--;
- month+=12;
- }
- if ( year > 0 )
- {
- printf("%d天",year);
- }
- if ( month > 0 )
- {
- printf("%d月",month);
- }
- if ( day > 0 )
- {
- printf("%d天",day);
- }
- if ( hour > 0 )
- {
- printf("%d小時",hour);
- }
- if ( minutes > 0 )
- {
- printf("%d分鐘",minutes);
- }
- if ( seconds > 0 )
- {
- printf("%d秒",seconds);
- }
- if ( milliseconds > 0 )
- {
- printf("%d微秒",milliseconds);
- }
- printf("\n");
- return 0;
- }
linux:
- #include <math.h>
- #include <stdio.h>
- #include <sys/time.h>
- int main(int argc,int **argv)
- {
- int i;
- struct timeval start;
- struct timeval end;
- double timeuse;
- char *exec_argv[4];
- if (argc==1)
- {
- printf("Error!\n");
- exit(0);
- }
- if (fork()==0)
- {
- for (i=0; i<argc; i++)
- {
- exec_argv[i]=argv[i+1];
- printf("[%d]:%s\n", i,exec_argv[i]);
- }
- printf("Child Create\n");
- execv(argv[1],exec_argv);
- }
- else
- {
- gettimeofday( &start, NULL );
- wait(NULL);
- gettimeofday( &end, NULL );
- timeuse = (1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec)/1000000;
- printf("time:%lfs\n",timeuse);
- }
- return 0;
- }