要求實作一個簡單的定時器,該程式要求的輸入格式為:
N prompt message
其中N表示時間,prompt message表示提示資訊。即過了N秒之後要在終端上顯示出提示資訊。一共用了三種方式實作:(1)最普通的方式,阻塞I/0+同步。(2)使用程序實作。(3)使用線程實作。
/*alarm.c*/
#include "../error.h"
#include<time.h>
int main(int argc,char *argv[])
{
int seconds;
char line[128];
char message[64];
while(NULL != fgets(line,sizeof(line),stdin))
{
if( 2 > sscanf(line,"%d %64[^\n]",&seconds,message))
fprintf(stderr,"Bad Command\n");
else
{
sleep(seconds);
fprintf(stdout,"%s\n",message);
}
}
return 0;
}
評注:
1.常量和函數比較的時候,将常量放在前面可以防止将==寫成=,因為編譯器會報錯。
2.sscanf為從一個字元緩沖區中格式化讀取資料。注意字元緩沖區放在第一個參數位置。使用%N可以控制讀取字元的數量,中括号的作用和正規表達式中的作用一樣,将不讀取的字元排除掉或者僅讀取中括号内指定的字元集,成功時,傳回讀取的參數的個數。
3.使用fgets+sscanf,簡化了從指令行中提取參數問題。
3.fgets從指定的檔案描述符中讀取一行字元串,失敗時傳回NULL。
4.對于每個函數都添加了判斷語句,特别有助于調試。
/*alarm_fork.c*/
#include <sys/types.h>
#include<wait.h>
pid_t pid;
if(2 > sscanf(line,"%d %64[^\n]",&seconds,message))
fprintf(stdout,"Bad command.\n");
continue;
pid = fork();
if((pid_t)-1 == pid)
{
error_abort("fork error...");
}
else if((pid_t)0 == pid)
sleep(seconds);
fprintf(stdout,"%s\n",message);
exit(0);
else
do
{
pid = waitpid((pid_t)-1,NULL,WNOHANG);
if((pid_t)-1 == pid)
{
error_abort("waitpid error...");
}
}while((pid_t)0 != pid);
1.pid_t這個類型在sys/types.h頭檔案中。
2.比較的時候要進行強制類型轉換,比如判斷程序id是不是為0,就要使用(pid_t)0 == pid這樣的判斷語句。
3.waitpid的第一個參數設定為-1,第三個參數設定為WNOHANG,表示非阻塞等待任何一個子程序。如果發現一個子程序傳回,立即再判斷是否還有其他程序傳回。可以迅速的釋放不再使用的資源。
/*alarm_thread.c*/
#include <pthread.h>
#include <time.h>
typedef struct alarm_tag
}alarm_t,*alarm_p;
void * alarm_thread(void * arg)
int status;
status = pthread_detach(pthread_self());
if(0 != status)
err_abort("detaching thread failure...",status);
alarm_p alarm = (alarm_p) arg;
sleep(alarm->seconds);
fprintf(stdout,"%s\n",alarm->message);
pthread_t thread;
alarm_p alarm;
alarm = (alarm_p) malloc(sizeof(alarm_t));
if( NULL == alarm)
error_abort("Allocating alarm failure...");
if(2 > sscanf(line,"%d %64[^\n]",&alarm->seconds,alarm->message))
fprintf(stdout,"%s\n","Bad command");
free(alarm);
status = pthread_create(&thread,NULL,alarm_thread,(void *)alarm);
if(0 != status)
err_abort("creating thread failure...",status);
1.Pthreads相關的類型,接口原型,常量都在pthread.h這個頭檔案中,編譯的時候要加 -lpthread.
2.由于線程的參數隻有一個,是以要将傳給線程的所有參數封裝到一個結構體中。
使用普通方式,多程序,多線程的比較
alarm一次隻能發出一個定時請求。如果發出一個10分鐘的請求,那麼必須要等十分鐘才能發出下一個請求。多程序解決了這個同步問題,但是在一個系統中,一個使用者能夠啟動的程序的數量是非常有限的,多線程受到這個影響要小得多。
多線程的幾個好處
(1)發掘多核計算潛力
(2)發掘程式自身的并發性
(3)子產品式的程式設計模型,可以更加清晰的表達不同僚件之間的關系
本文轉自hipercomer 51CTO部落格,原文連結:http://blog.51cto.com/hipercomer/908959