Linux下时间和定时器 ZZ

luffy 发表于 2010-01-11 22:05:42

转自http://blog.chinaunix.net/u1/35065/showart_1870601.html
重点读了第三种方法。文章写得很好,加了一点点注释

可参考 http://linux.die.net/man/3/timer_settime
              http://linux.die.net/man/2/setitimer 
              http://opengroup.org/onlinepubs/007908799/xsh/timer_settime.html

一、问题的提出
我们开发程序时,经常会遇到时间和定时器的问题,为了更好的使用时间和定时器,现在列举一个一些时间结构体、函数和定时器。

二、解决思路
1.时间类型
1) time_t是一个长整型,一般用来表示用1970年以来的秒数。

2)struct timeval有两个成员,一个是秒,一个是微妙。

struct timeval
{             
long tv_sec;        /* seconds */        
long tv_usec;   /* microseconds */  
};

3) struct timespec有两个成员,一个是秒,一个是纳秒。

struct timespec
{
   time_t tv_sec;          /* seconds */
   long    tv_nsec;        /* nanoseconds */
};

4) struct tm是直观意义上的时间表示方法

struct tm
{                  
int     tm_sec;         /* seconds */                   
int     tm_min;         /* minutes */                     
int     tm_hour;        /* hours */                  
int     tm_mday;         /* day of the month */                        
int     tm_mon;         /* month */                    
int     tm_year;        /* year */                  
int     tm_wday;         /* day of the week */                        
int     tm_yday;        /* day in the year */                          
int     tm_isdst;        /* daylight saving time */           
};

5)

     struct timeb
     {
        time_t    time;            //从1970来经过的秒数
        unsigned short millitm; //毫秒
        short     timezone;        //时区
        short     dstflag;//为日光节约时间的修正值,如果为非0代表启用日光节约修正
};

   6)

      struct timezone
{
         int tz_minuteswest;//和格林尼治时间相差多少分
         int tz_dsttime;//日光节约时间的状态 
};

   日光节约时间:夏时制。

2.时间函数
1) char *asctime(const struct tm *timeptr)

将时间和日期以字符串格式显示。

2)clock_t clock(void)

   取得进程占用cpu的大约时间。

3)char *ctime(const time_t *timep)

将时间和日期以字符串格式显示。

4) double difftime(time_t time1, time_t time0)

计算时间time1和time0间的差距。

5) int ftime(struct timeb *tp)

   取得目前的时间和日期。

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

   取得目前的时间。

7)strcut tm *gmtime(const time_t *timep)

   time_t结构时间转tm结构时间,tm为UTC时区。

8) struct tm *localtime(const time_t *timep)

   将time_t结构时间转tm结构时间,tm是当地时区。

9)time_t mktime(struct tm *timeptr)

   将tm结构时间转换为time_t。

10) int settimeofday(const struct timeval *tv, const struct timezone *tz)

   设置时间为tv,设置时区为tz。

11) size_t strftime(char *s, size_t max, const char *format, const struct tm *tm)

   将参数tm的时间结构依照参数format所指定的字符串格式做转换,转换后的字符串将复制到参数s所指的字符串数组中,该字符串的最大长度为参数max所控制。

12) time_t time(time_t *t)

   取得目前的时间,时间按照UTC。

13) void tzset(void)

   从环境变量TZ取得目前当地的时间。

3.延迟函数
主要的延迟函数有:sleep(),usleep(),nanosleep(),select(),pselect().

1) unsigned int sleep(unsigned int seconds)

延时seconds秒。

2) void usleep(int micro_seconds)

延时 micro_seconds微妙

3) int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)

延时的时间为rqtp,如果nansleep被信号中断,且rmtp不为NULL,则rmtp指定的位置上包含的就是剩余时间。

4) int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)

如果将readfds, writefds, exceptfds置为NULL,timeout为非零,则延时timeout。

5) int pselect(int maxfdp1, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec tsptr, const sigset_t *sigmask)

如果将readfds, writefds, exceptfds置为NULL,tsptr为非零,则延时tsptr。

3.定时器
1) unsigned int alarm(unsigned int seconds)

设置一个定时器,在seconds秒后超时,当定时器超时时,产生SIGALRM信号。如果不忽略或不捕捉此信号,则其默认动作是终止调用该alarm函数的进程,如果设置了SIGALRM信号处理函数,则会执行该信号处理函数。

每个进程只能有一个闹钟时钟。如果在调用alarm时,以前已为该进程设置过闹钟时钟,而且它还没有超时,则将该闹钟时钟的余留值作为本次alarm函数调用的值返回,以前登记的闹钟时钟则被新值代替。

例子:

void sigalrm_fn(int sig)

{

printf("alarm!\n");

alarm(2);

return;

}

 

int main(void)

{

signal(SIGALRM, sigalrm_fn);

alarm(1);

while(1) pause();

}

 

2) POSIX:XSI间隔定时器

int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);

struct itimerval

{
    struct timeval it_interval; /* 计时器重启动的间歇值 */
    struct timeval it_value;    /* 计时器安装后首先启动的初始值 */
};

 

   getitimer()用计时器的当前值填写value指向的结构体。
setitimer()将value指向的结构体设为计时器的当前值,如果ovalue不是NULL,将返回计时器原有值。

which:间歇计时器类型,有三种选择:

l         ITIMER_REAL //数值为0,计时器的值实时递减,发送的信号是SIGALRM。

l         ITIMER_VIRTUAL //数值为1,进程执行时递减计时器的值(虚拟时间),发送的信号是SIGVTALRM。

l         ITIMER_PROF //数值为2,虚拟时间和进程的系统时间递减,发送的信号是SIGPROF。

itimerval结构中的it_value是减少的时间,当这个值为0的时候就发出相应的信号了. 然后再将it_value设置为it_interval值. 也就是先处理it_value中设置的值,为0后发送信号(根据which来判断发送什么信号),之后都是根据it_interval的值发送信号。若it_value和it_interval都为0,也就没有相应的信号产生了。

和alarm()一样,由于信号的限制,POSIX:XSI间隔定时器对于每个进程来说最多只有3个定时器。

例子:

void sigroutine(int signo)

{

switch (signo)

{

case SIGALRM:

printf("Catch a signal -- SIGALRM \n");

signal(SIGALRM, sigroutine);

break;

 

case SIGVTALRM:

printf("Catch a signal -- SIGVTALRM \n");

signal(SIGVTALRM, sigroutine);

break;

}

return;

}

 

int main()

{

struct itimerval value, ovalue, value2;

sec = 5;

printf("process id is %d\n", getpid());

signal(SIGALRM, sigroutine);

signal(SIGVTALRM, sigroutine);

value.it_value.tv_sec = 1;

value.it_value.tv_usec = 0;

value.it_interval.tv_sec = 1;

value.it_interval.tv_usec = 0;

setitimer(ITIMER_REAL, &value, &ovalue);

value2.it_value.tv_sec = 0;

value2.it_value.tv_usec = 500000;

value2.it_interval.tv_sec = 0;

value2.it_interval.tv_usec = 500000;

setitimer(ITIMER_VIRTUAL, &value2, &ovalue);

for(;;)

;

}

3)POSIX:TMR间隔定时器

int timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid)

   进程可以通过调用timer_create()创建特定的定时器,定时器是每个进程自己的,不是在fork时继承的。timer_create的参数clock_id说明定时器是基于哪个时钟的,*timerid装载的是被创建的定时器的ID。timer_create函数创建了定时器,并将他的ID放入timerid指向的位置中。参数evp指定了定时器到期要产生的异步通知。如果evp为NULL,那么定时器到期会产生默认的信号,对CLOCK_REALTIMER来说,默认信号就是SIGALRM。对那些定时器到期时要产生除默认信号之外的其它信号的定时器来说,程序必须将evp->sigev_signo设置为期望的信号码。struct sigevent 结构中的成员evp->sigev_notify说明了定时器到期时应该采取的行动。通常,这个成员的值为SIGEV_SIGNAL,这个值说明在定时器到期时,会产生一个信号。程序可以将成员evp->sigev_notify设为SIGEV_NONE来防止定时器到期时产生信号。

 

如果几个定时器产生了同一个信号,处理程序可以用evp->sigev_value来区分是哪个定时器产生了信号。要实现这种功能,程序必须在为信号安装处理程序时,使用struct sigaction的成员sa_flags中的标志符SA_SIGINFO。

clock_id的取值为以下:

CLOCK_REALTIME :Systemwide realtime clock.

CLOCK_MONOTONIC:Represents monotonic time. Cannot be set.

CLOCK_PROCESS_CPUTIME_ID :High resolution per-process timer.

CLOCK_THREAD_CPUTIME_ID :Thread-specific timer.

CLOCK_REALTIME_HR :High resolution version of CLOCK_REALTIME.

CLOCK_MONOTONIC_HR :High resolution version of CLOCK_MONOTONIC.

 

struct sigevent

{

int sigev_notify; //notification type

int sigev_signo; //signal number

union sigval   sigev_value; //signal value

void (*sigev_notify_function)(union sigval);

pthread_attr_t *sigev_notify_attributes;

}

union sigval

{

int sival_int; //integer value

void *sival_ptr; //pointer value

}

通过将evp->sigev_notify设定为如下值来定制定时器到期后的行为:

l         SIGEV_SIGNAL: 发送由evp->sigev_sino指定的信号到调用进程,evp->sigev_value的值将被作为siginfo_t结构体中si_value的值。

l         SIGEV_NONE:什么都不做,只提供通过timer_gettime和timer_getoverrun查询超时信息。

l         SIGEV_THREAD: 以evp->sigev_notification_attributes为线程属性创建一个线程,在新建的线程内部以evp->sigev_value为参数调用evp->sigev_notification_function。

 

int timer_delete(timer_t timerid);

删除ID为timerid的POSIX:TMR定时器。

int timer_settime(timer_t timerid,int flags,const struct itimerspec *value,struct itimerspec *ovalue);

struct     itimerspec   
{   
       struct     timespec   it_interval; //定时器周期值
       struct     timespec   it_value;     //定时器到期值
};   

      timer_settime负责启动或停止timer_create创建的定时器。参数flag说明定时器使用的是相对时间还是绝对时间。相对时间与POSIX:XSI定时器使用的策略类似,而绝对时间的精确度更高。参数vaule指向的值来设置timerid指定的定时器。如果ovalue不为NULL,timer_settime就将定时器以前的值放在ovalue指定的位置上。如果定时器正在运行,那么*ovalue的成员it_value非零,并包含了定时器到期之前剩余的时间。

TIMER_ABSTIME表示绝对时间;
如果flag没有设定为TIMER_ABSTIME,则定时器从调用开始在it_value内超时;即value->it_value代表计时器第一次超时的时间。
如果设定为TIMER_ABSTIME,该函数表现为时间直到下一次超时被设定为it_value指定的绝对时间和与timerid相联的时钟值的差值。如果已经到了it_value指定的值,那么超时后的处理就会立即执行。

定时器的再装由value的it_interval成员值来设定。



int timer_gettime(timer_t timerid,struct itimerspec *value);

获得一个活动定时器的剩余时间。

int timer_getoverrun(timer_t timerid);

       有可能一个定时器到期了,而同一定时器上一次到期时产生的信号还处于挂起状态。在这种情况下,其中的一个信号可能会丢失。这就是定时器超限。程序可以通过调用timer_getoverrun来确定一个特定的定时器出现这种超限的次数。定时器超限只能发生在同一个定时器产生的信号上。由多个定时器,甚至是那些使用相同的时钟和信号的定时器,所产生的信号都会排队而不会丢失。

例子:

编译方法:

     gcc -o example example.c   -lrt   -lpthread   

那个rt库就是POSIX   realtime   extension的库。

 

#include   <stdio.h>  

#include   <time.h>  

#include   <signal.h>  

#include   <string.h>//不然会出现对memset函数的警告

void  

handle   (union sigval   v)  

{  

      time_t   t;  

      char   p[32];  

 

      time   (&t);  

      strftimep,   sizeof   (p),   "%T",   localtime   (&t));  

      printf("%s   thread   %lu,   val   =   %d,   signal   captured.\n",   p,   pthread_self(), v.sival_int);  

      return;  

}  

   

int create   (int   seconds,   int   id)  

{  

      timer_t   tid;  

      struct   sigevent   se;  

      struct   itimerspec   ts,   ots;  

      memset   (&se,   0,   sizeof   (se));  

      se.sigev_notify   =   SIGEV_THREAD;  

      se.sigev_notify_function   =   handle;  

      se.sigev_value.sival_int   =   id;   //作为handle()的参数

      if   (timer_create   (CLOCK_REALTIME,   &se,   &tid)   <   0)  

          {  

              perror   ("timer_creat");  

              return   -1;  

          }  

      puts   ("timer_create   successfully.");  

      ts.it_value.tv_sec   =   3;  

      ts.it_value.tv_nsec   =   0;  

      ts.it_interval.tv_sec   =   seconds;  

      ts.it_interval.tv_nsec   =   0;  

      if   (timer_settime (tid,   TIMER_ABSTIME,   &ts,   &ots)   <   0)  

          {  

              perror   ("timer_settime");  

              return   -1;  

          }  

      return   0;  

}  

   

int   main   (void)  

{  

      create   (3,   1);  

      create   (5,   2);  

      for   (;;)  

          {  

              sleep   (10);  

          }  

}

三、总结
Linux下定时器主要使用上面介绍的三种定时器。

关键词(Tag): linux 定时器

我的2009

luffy 发表于 2010-01-01 14:40:15

09年,是我过得最充实和有趣的一年。 

这一年,跟着hehehahi大神,学会了轮滑,在北航新主楼内摔过N次,不过草坪也被踩过N次(草坪是不会刹车的人的绝好刹车地点)。虽然还不会刹车。。。马马虎虎算我会了吧。 

这一年,跟着hehehahi大神,学会了游泳,虽然只是蛙泳,虽然还不会踩水,虽然自由泳很难看,不过今年要拿下深水证! 

这一年,跟着hehehahi大神,败了一只正儿八经的羽毛球拍,开始学习打羽毛球,希望今年能跟着院队混一下比赛。 

PS:由上可见,hehehahi大神是运动全能啊,膜拜一下。 

跟着qingya组织,各种腐败,尝到了很多好东西,原来我以为我不怎么在意吃喝,现在觉得人人心里都有一条大馋虫。 

因为《阿呆》,第一次看懂了五线谱,激动的泪流满面,不过现在又不认得了。 

感谢ll和flq,陪我见了道长一面,还做了影像记录,去年的生日我会永远记得。 

感谢好多人,在你们的鼓励下,第一次参加了马拉松,顺利拿下了半程,今年我要拿下全程。 

感谢cindy同学,终于看到了怨念了5年的音乐剧--《cats》,这次还是英国的团~ 

今年还有好多第一次: 
第一次看了IMAX电影--变2, 
第一次看了3D电影--《UP》, 
第一次看了话剧--《恋爱的犀牛》。
第一次在大家面前跳舞,还是李孝利的anymotion。 
第一次说相声,还好中间没有忘词。
第一次组织大家排剧,深感导演的不易。 
第一次被电面,虽然最后被默拒。。。
第一次玩了三国杀,我是outman。。。

这一年,看了近100本书,技术的,心理学的,社会学的,小说类的,传记类的,还有几本诗集。。
这一年,看了近200部电影,虽然豆瓣上的评价不一,还好大多数没让我失望。
之于我而言,09年的年度影视和年度书籍是《欲望都市》和《我爱问连岳》,借用朋友的一句话,这是在继Friends之后,给予我的再一次性教育和爱教育。 


2010年要做点什么,还没想好,先祝今年诸事顺利。
关键词(Tag): 总结 2009
阅读178次 评论2条 个人主页 扔小纸条 文件夹:

记我的第一次北马

luffy 发表于 2009-10-22 09:08:38

        很早就惦记着今年的北马,8月底从大运村搬回来以后,就开始准备9公里马拉松了,大约有一个多月,每周跑上两次,然后每次跑步的长度由6圈开始2圈2圈的递增,一直到20圈。8km的距离跑了有3次,然后就十一了,去上海南京等地游玩,出去玩挺累的,就当有氧运动了,回来以后的那周也就跑了一次10圈左右,算是恢复性训练吧,然后周日就开始了第一次马拉松之旅了。

      18号那天早晨定了两个闹钟,招行办卡送的那个表偏差太大,5点就开始闹了,然后忐忑的睡到了手机响,速度的洗漱,啃了几口面包,烫了一袋奶。走到了电梯口才意识到现在太早,电梯还没开,悲剧的走下了十五楼。。 到了南门6点5分,师弟师妹已经在等我了,寒啊,迟到了几分钟。早晨好冷,还好没等几分钟498就到了,然后转地铁到前门,在出地铁前上了一次厕所,到广场上面的时候就快7点半了。我们站着各吃了块巧克力,然后师妹要跑全程,就此分开。很容易找到了收衣服的车,收包的时间是七点半,就赶紧把外套长裤脱下来塞进包里,在这里抱怨一下今年发的那个包,质量好差,就拿了一路,绳子已经快从包口掉出来了。。。脱了外套长裤那个冷啊,还好听了michael的话买了个一次性雨衣,虽然只是一层薄薄的塑料纸,不过不透风还是很好的,唯一的缺点就是太短了,小腿完全暴露在外。我们跟着台子上的美女做了一会儿健身操,快8点的时候,又想去厕所。。这时候去厕所,排队的人少了,不过要穿过层层人群才能过去,上完厕所回来的路上听见了枪响,十一运会的比赛已经开始了,前面橙色一片全是人,尝试前进了几步,逃离了边缘地带,还算比较暖和,就把雨衣收了。这时候想起了看的帝企鹅的纪录片,帝企鹅爸爸们在孵蛋的时候也是围在一起抵御凛冽的寒风,不过它们要轮流站在外面,相比而言我们还算很幸运,呆在人群里面就好了。

        8点15业余组开始比赛,不过我们这块开始移动的时候已经过了两三分钟了,囧。第一公里基本都是走过去的,几万人同时起跑,还有很多人在照相!!选手的岁数差别也很大,我见到的最小的那个小女孩大概也就三四岁,因为还没到我的腿高,在父母的陪同下跑迷你马拉松,很多头发雪白的老人也在参加,而且有不少是半程全程。不过三四十岁的选手太少,大部分还都是老外。不一会迷你马拉松的终点就到了,刚开始就结束的感觉。这时候我就有了一个想法,就是不去9公里的终点而是接着跑半程。赛前研究了一下手册,原来不同赛事的选手的号码布的颜色不同,比如我报的9公里就是绿色的,迷你是黄色的,半程是蓝色的,全程是白色的。要想混下去,就得把号码布取下来,本来我的号码布就是用透明胶粘上去的,很早就取下来拿在手心。果不其然,小胖和我一起进半程赛道的时候,周围的志愿者就热心的对他说9公里的终点在那个方向……收容车的大妈也对他说如果不摘下的话,路上的裁判是不让他继续跑的。可怜小胖同学是把号码布缝在衣服上的,就用蛮力撕了下来。前几公里我们还边说边跑的,现在小胖同学有点喘,又跑了4公里之后我们就分开了。这时候我才理解了半程还是可以结伴而行,但是全程千万不要。每个人都有自己的节奏,强跟别人的节奏会把自己拖垮的。 

       独自上路后,稍微快了一点,大约6分钟1公里,之前的水站没怎么利用,喝了一点水而已,现在就很珍惜水站的出现了,看过帖子说前面10公里不建议喝运动饮料,之前喝的水比较多,和小胖分开以后我拿的都是运动饮料了,毕竟已经跑了一个多小时了。水我是进了水站要一瓶,然后跑的时候慢慢的一口一口的喝,喝到下一个水站,觉得这样还不错。。。。到了19公里的时候,开始起风了,然后到终点的时候,刚好2小时29分,这时我也被吹的干透透,手也是冰凉的,到了终点以后又顺着小跑了一段。跑步的时候没什么感觉,停下的时候觉得腿还是挺酸的。又找不到地方压腿,只好在路边的台阶上抻抻小腿,左右弓步的压腿。本来没计划跑这么多,对长跑之后的压腿也没怎么研究,导致我周一周二腿疼了两天。。。 

        一路上喝了三瓶佳得乐,得到了一件made in taiwan的nike速干T恤(穿上感觉是像是鲁能泰山队的队服),还有路上的无数北京市民的热情加油,这50块钱花的超值啊,木哈哈。 

        半程跑下来,可能是跑的比较慢的缘故吧,脚腕啊,膝盖啊,都没有觉得疼。不过按照这个速度的话,必然跑不进5小时。明年要跑全程的话,还要加强锻炼,鉴于北京的天气转冷,锻炼方式转为游泳和瑜伽,明年开春再接着跑吧! 

       PS:今天早晨起来的时候,腿终于不疼了,不知道明年全程下来是不是得疼一 周呢?
关键词(Tag): 北京 马拉松 半程

这是一个关于爱的故事--《灿烂千阳》

luffy 发表于 2009-09-09 17:17:17

        读到最后几章的时候,一直流泪不止,以致和室友说话的时候声音都哽咽了,比起《》的四星半,这本书打得是纯粹的五星。       

         私生女玛丽雅姆从小就渴望父亲的爱,对得不到的这份爱的渴望那么强大,强大到忽略了母亲的爱。没有等到约好接她来看电影的父亲,她决定离开了她生活了15年的小泥屋,去找自己的父亲。得到的却是露宿的一宿和父亲在窗帘后闪现的脸,此时她才明白了母亲,认识到了父亲的虚伪。这个决定改变了玛丽雅姆的一生,母亲的自杀,父亲的懦弱,让她嫁给了大她二十多岁的修鞋匠。又由于她的屡次流产,成了丈夫泄愤的对象,冷嘲热讽加拳打脚踢。她就一直这么卑微的活着。       
        
         我很难理解玛丽雅姆是怎么生存下去的,书在后面写到“她躲在自己心灵的一个遥远角落,独自度过了这些岁月。那儿是一片干旱贫瘠的土地,没有希望,也没有哀伤;没有梦想,也没有幻灭。那儿无所谓未来。那儿的过去只留下这个教训:爱是使人遍体鳞伤的错误,而它的帮凶,希望,则是令人悔恨莫及的幻想。无论什么时候,若这一对剧毒的两生花开始在那片干涸的土地上生长出来,玛丽雅姆就会将它们连根拔除。她把它们拔起来,还没拿稳就赶紧将其掩埋。” 生活将一个渴望爱的人变成了一个没有希望没有爱的人,并赋予这个内心充满恐惧的女人惊人的耐力。隐忍,貌似在东方被看做一种美德,在这里我看到的却是它对人性的彻底摧残。   

        莱拉的到来打破了玛丽雅姆日复一日的生活。莱拉可以说得上是玛丽雅姆的下一辈(她的家庭环境很好,受过良好的教育,和帅气的塔里克有过炽热的爱情,但是两个兄长死于圣战,父母又在逃离阿富汗的搬家中死于流弹),但在阿富汗这个神奇的国度,她们俩又分享了一个六十多岁的丈夫,且不说拉希德(她们的丈夫,很讨厌这个名字)是用怎样的手段让十四岁的莱拉嫁给他的。莱拉生了一个女儿阿兹莎,我们可怜的玛丽雅姆对莱拉表现出了十足的敌意,但是我对玛丽雅姆却恨不起来,莱拉的到来让她的地位更低贱,我们有什么理由去责怪玛丽雅姆呢。   

        一次貌似平常的家庭暴力由于莱拉的阻止变成了未完成状态,玛丽雅姆对莱拉的态度出现了微妙的变化,居然有人肯为了她而挺身而出,在她的生命里,这是第一次。hope is a good thing,现在她渴望和莱拉分享三杯茶,渴望看到阿兹莎,而阿兹莎对玛丽雅姆也有着出奇的好感,她是最需要玛丽雅姆的人。玛丽雅姆也是第一次碰到了对她毫无保留表达爱意的人。       

         姐妹俩的第一次出逃计划因一个男子的告密而失败,玛丽雅姆和莱拉也遭到了濒死的惩罚。我欣喜的看到隐忍了二十多年的玛丽雅姆居然也有了勇气来改变自己的命运,这一切都是爱的力量。       

         后面的故事很惊险,莱拉为拉希德生了一个儿子,并在几年后重新见到了塔里克,因为塔里克而引发的争吵演变成一场斗争,在那场斗争中,玛丽雅姆为了挽救莱拉,用铁锨结束了拉希德的生命。玛丽雅姆为了成全莱拉和塔里克的幸福生活,去法院自首。书中最后是这样写的“当她即将离开世界的时候,她是一个付出了爱也得到了爱的女人。她以朋友、同伴、监护人的身份离开这个世界。以母亲的身份。她终究成了别人眼中的重要人物。”       

         从这里开始,到莱拉去探访玛丽雅姆的故居,重温了玛丽雅姆看似平凡却又不平凡的一生,作者在前面的铺垫此时都有了对应,看这部分的时候有种巨大的满足感,像是终于等到了命运的审判,此时早已泪流满面。        

        关于这本书的女主角,我执拗的认为只有玛丽雅姆一人。
关键词(Tag): 女性 阿富汗 灿烂千阳

ubuntu 初装记

luffy 发表于 2009-07-02 17:40:46

首先感谢小方同志帮我把电脑的硬盘换了进去,然后非常感谢gada同学帮我装了两次机器:)
下面罗列一下要点,以备后用。。

第一需要注意的是分区,对于我40G的硬盘,gada同学这样的分区方法是不错的
     /boot  128M
     /      2G
    /home  10G
    /var   13G
    /usr   13G
    swap   1G

第二要注意的就是,开机进入系统后先修改源的设置:
    sudo gedit /etc/apt/sources.list
    输入密码之后,添加以下语句,然后保存退出。
    deb ftp://openware.byr.edu.cn/pub/mirror/ubuntu/ intrepid main multiverse restricted universe
    deb ftp://openware.byr.edu.cn/pub/mirror/ubuntu/ intrepid-backports main multiverse restricted universe
    deb ftp://openware.byr.edu.cn/pub/mirror/ubuntu/ intrepid-proposed main multiverse restricted universe
    deb ftp://openware.byr.edu.cn/pub/mirror/ubuntu/ intrepid-security main multiverse restricted universe
    deb ftp://openware.byr.edu.cn/pub/mirror/ubuntu/ intrepid-updates main multiverse restricted universe

     然后 sudo apt-get update

第三:就是要安装中文输入法,怎么说呢,自带的那个scim不完整,先卸载掉,然后再装中文输入法。
    sudo apt-get remove scim
    sudo apt-get install scim
    sudo apt-get install scim-chinese

第四:安装JAVA环境支持
1、安装JAVA解释器(中间有一对话框,是询问是否接受协议的,用TAB键移动到OK,回车即可)
(1)执行命令
  sudo apt-get install sun-java6-jre
(2)运行命令
  sudo apt-get install sun-java6-jdk
2、设置默认的JAVA解释器
(1)运行命令
  sudo update-alternatives --config java
3、配置JAVA环境变量
(1)运行命令
  sudo gedit /etc/environment
(2)在文件内添加两行
  CLASSPATH=.:/usr/lib/jvm/java-6-sun/lib
  JAVA_HOME=/usr/lib/jvm/java-6-sun
(3)保存关闭
(4)运行命令
  sudo gedit /etc/jvm
(5)在文件顶部添加
   /usr/lib/jvm/java-6-sun
4、安装浏览器的JAVA Plugin
  运行命令
  sudo apt-get install sun-java6-plugin

 第五:安装eclipse
  sudo apt-get install eclipse

 第六:安装qq
   去这里http://im.qq.com/qq/linux/download.shtml 下载ubuntu版本的qq
    运行命令  dpkg -i linuxXXXXXXX.deb
 第七:  安装压缩及解压缩RAR文件的程序
   sudo apt-get install rar unrar
  第八:修改vim设置
   sudo apt-get install vim
   然后进入/etc目录下,运行 sudo gedit vimrc
   在文件里添加:syntax on来设置语法高亮显示(如果此时语法还是没有高亮显示,那么在/etc目录下的profile文件中添加以下语句:
export TERM=xterm-color,这个我没用到哦)
   设置Windows风格的C/C++自动缩进(添加以下set语句到vimrc中)
              1)设置(软)制表符宽度为4:
                            set tabstop=4
                            set softtabstop=4
              2)设置缩进的空格数为4
                            set shiftwidth=4
              3)设置自动缩进:即每行的缩进值与上一行相等;使用 noautoindent 取消设置:
                            set autoindent
              4)设置使用 C/C++ 语言的自动缩进方式:
                           set cindent
              5)设置C/C++语言的具体缩进方式(以我的windows风格为例):
                           set cinoptions={0,1s,t0,n-2,p2s,(03s,=.5s,>1s,=1s,:1s
              6)如果想在左侧显示文本的行号,可以用以下语句:
                          set nu
              7)最后,如果没有下列语句,就加上吧:
                          if &term=="xterm"
                                   set t_Co=8
                                   set t_Sb=^[[4%dm
                                   set t_Sf=^[[3%dm
                          endif
     第九 安装火狐插件,能够看youku视频。
     在这个网址下载 MediaWrap 0.1.7.3插件,就能看咯。https://addons.mozilla.org/en-US/firefox/addon/1879
    
参考:
http://blog.sina.com.cn/s/blog_464e80580100aalm.html
http://www.xxlinux.com/linux/article/development/soft/20080213/13766.html
关键词(Tag): 安装 ubuntu 8.10