《Linux操作系统 - 高级编程》第二部分 进程(第4章 进程相关)

4.1 Linux时间函数解析

4.1.1 Linux下常用时间类型

Linux下常用时间类型有四种:time_t、struct tm、struct timeval、struct timespec
 time_t时间类型
time_t类型在time.h中定义:

#ifndef __TIME_T  
#define __TIME_T  
typedef  long  time_t;  
#endif  

可见,time _t实际是一个长整型。其值表示为从UTC(coordinated universal time)时间1970年1月1日00时00分00秒(也称为Linux系统的Epoch时间)到当前时刻的秒数。由于time_t类型长度的限制,它所表示的时间不能晚于2038年1月19日03时14分07秒(UTC)。为了能够表示更久远的时间,可用64位或更长的整形数来保存日历时间,这里不作详述。

使用time()函数获取当前时间的time_t值,使用ctime()函数将time_t转为当地时间字符串。
备注:UTC时间有时也称为GMT时间,其实UTC和GMT两者几乎是同一概念。它们都是指格林尼治标准时间,只不过UTC的称呼更为正式一点。两者区别在于前者是天文上的概念,而后者是基于一个原子钟。

 struct tm时间类型
tm结构在time.h中定义:

#ifndef _TM_DEFINED  
struct tm{  
    int tm_sec; /*秒 - 取值区间为[0, 59]*/  
    int tm_min; /*分 - 取值区间为[0, 59]*/  
    int tm_hour; /*时 - 取值区间为[0, 23]*/  
    int tm_mday; /*日 - 取值区间为[1, 31]*/  
    int tm_mon; /*月份 - 取值区间为[0, 11]*/  
    int tm_year; /*年份 - 其值为1900年至今年数*/  
    int tm_wday; /*星期 - 取值区间[0, 6],0代表星期天,1代表星期1,以此类推*/  
    int tm_yday; /*从每年的1月1日开始的天数-取值区间为[0, 365],0代表1月1日*/  
    int tm_isdst; /*夏令时标识符,使用夏令时,tm_isdst为正,不使用夏令时,tm_isdst为0,不了解情况时,tm_isdst为负*/  
};  
#define _TM_DEFINED  
#endif  

ANSI C标准称使用tm结构的这种时间表示为分解时间(broken-down time)。

使用gmtime( )和localtime( )可将time_t时间类型转换为tm结构体;
使用mktime( )将tm结构体转换为time_t时间类型;
使用asctime( )将struct tm转换为字符串形式。

 struct timeval时间类型
timeval结构体在time.h中定义:

struct tmieval{  
    time_t tv_sec; /*秒s*/  
    suseconds_t tv_usec; /*微秒us*/  
};  

设置时间函数settimeofday( )与获取时间函数gettimeofday( )均使用该事件类型作为传参。

 struct timespec时间类型
timespec结构体在time.h定义:

struct timespec{  
    time_t tv_sec; /*秒s*/  
    long tv_nsec; /*纳秒ns*/  
};

4.1.2 Linux下常用时间函数

Linux下常用时间函数有:time( )、ctime( )、gmtime( )、localtime( )、mktime( )、asctime( )、difftime( )、gettimeofday( )、settimeofday( )
 time()函数

表1 time() 函数

这里写图片描述

功能: 获取当前的系统时间,返回的结果是一个time_t类型,其实就是一个大整数,其值表示从CUT(Coordinated Universal Time)时间1970年1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻的秒数。然后调用localtime将time_t所表示的CUT时间转换为本地时间(我们是+8区,比CUT多8个小时)并转成struct tm类型。

补充说明:time函数的原型也可以理解为 long time(long *tloc),即返回一个long型整数。因为在time.h这个头文件中time_t 实际上就是:

#ifndef _TIME_T_DEFINED  
#define _TIME_T_DEFINED /* avoid multiple defines of time_t */  
    typedef long time_t; /* time value */  
#endif

【参见附件/time1.c】

#include <time.h>  
#include <stdio.h>  
int main(void)  
{  
	time_t t;   
	printf("The number of seconds since January 1, 1970 is %ld\n",t);  
	return 0;  
} 

执行结果如下:
这里写图片描述
time函数也常用于随机数的生成,用日历时间作为种子。
【参见附件/time2.c】

#include <stdio.h>  
#include <time.h>  
#include<stdlib.h>  
int main(void)  
{  
    int i;  
    srand((unsigned) time(NULL));  
    printf("ten random numbers from 0 to 99:\n");  
    for(i = 0;i < 10;i++)  
    {  
        printf("%d\n",rand()%100);  
    }  
    return 0;  
}  

执行结果如下:
这里写图片描述
 ctime( )函数

表2 ctime()函数

这里写图片描述

功能:ctime( )将参数timep指向的time_t时间信息转换成实际所使用的时间日期表示方法,并以字符串形式返回。若再调用相关的时间日期函数,此字符串可能会被破坏。返回时间字符串格式为:星期 月 日 小时:分:秒 年。
【参见附件/ctime.c】

#include <stdio.h>   
#include <time.h>   
int main()   
{  
    time_t t;  
    time(&t);  
      
    printf("Today's date and time: %s",ctime(&t));  
    return 0;   
}  

执行结果如下:
这里写图片描述
 gmtime( )函数

表3 gmtime()函数

这里写图片描述

功能:gmtime( )将参数timep指向的time_t时间信息转换成以tm结构体表示的GMT时间信息,并以struct tm*指针返回。
GMT:GMT是中央时区,北京在东8区,相差8个小时,所以北京时间=GMT时间+8小时。
【参见附件/gmtime.c】

#include <stdio.h>   
#include <time.h>   
int main(void)  
{  
    char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  
    time_t timep;  
    struct tm *p_tm;  
    timep = time(NULL);  
    p_tm = gmtime(&timep); /*获取GMT时间*/  
    printf("%d-%d-%d ", (p_tm->tm_year+1900), (p_tm->tm_mon+1), p_tm->tm_mday);  
    printf("%s %d:%d:%d\n", wday[p_tm->tm_wday], p_tm->tm_hour, p_tm->tm_min, p_tm->tm_sec);  
}  

运行结果:
这里写图片描述
 localtime( )函数

表4 localtime()函数

这里写图片描述

功能:localtime( )将参数timep指向的time_t时间信息转换成以tm结构体表示的本地时区时间(如北京时间= GMT+小时)。
【参见附件/localtime.c】

#include <time.h>   
#include <stdio.h>   
int main()  
{  
    time_t timer;  
    struct tm *tblock;  
    timer = time(NULL);  
    tblock = localtime(&timer);  
    printf("Local time is: %s",asctime(tblock));  
    return 0;   
}   

执行结果如下:
这里写图片描述
 mktime( )函数

表5 mktime()函数

这里写图片描述

功能:mktime( )将参数p_tm指向的tm结构体数据转换成从1970年1月1日00时00分00秒至今的GMT时间经过的秒数。
【参见附件/mktime.c】

#include <time.h>
#include <stdio.h>

int main(void)  
{  
    time_t timep;
    struct tm *p_tm;  
    timep = time(NULL);  
    printf("time( ):%d\n", timep);  
    p_tm = localtime(&timep);  
	timep = mktime(p_tm);  
    printf("time( )->localtime( )->mktime( ):%d\n", timep);  
    return 0;  
}

运行结果:
这里写图片描述
 asctime( )函数

表6 asctime() 函数

这里写图片描述

功能:asctime( )将指向的tm结构体数据转换成实际使用的时间日期表示方法,
【参见附件/asctime.c】

#include <stdio.h>   
#include <string.h>   
#include <time.h>  
int main()   
{  
    struct tm t;  
    char str[80];  
    t.tm_sec = 1;  
    t.tm_min = 3;  
    t.tm_hour = 7;  
    t.tm_mday = 22;  
    t.tm_mon = 11;  
    t.tm_year = 56;  
    t.tm_wday = 4;  
    t.tm_yday = 0;  
    t.tm_isdst = 0;  
    strcpy(str,asctime(&t));  
      
    printf("%s",str);  
  
    return 0;   
}  

执行结果如下:
这里写图片描述
 difftime( )函数

表7 difftime() 函数

这里写图片描述

功能:difftime( )比较参数timep1和timep2时间是否相同,并返回之间相差秒数。
【参见附件/difftime.c】

#include <time.h>
#include <stdio.h>

int main(void)  
{  
    time_t timep1, timep2;  
    timep1 = time(NULL);  
    sleep(2);  
    timep2 = time(NULL);  
    printf("the difference is %f seconds\n", difftime(timep1, timep2));  
    return 0;  
}  

执行结果:
这里写图片描述
 gettimeofday( )函数

表8 gettimeofday()函数

这里写图片描述

功能:gettimeofday( )把目前的时间信息存入tv指向的结构体,当地时区信息则放到tz指向的结构体。

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};
struct timezone {
    int tz_minuteswest;     /* minutes west of Greenwich */
    int tz_dsttime;         /* type of DST correction */
};

使用time函数族获取时间并输出指定格式字符串例子(strftime( )函数):
【参见附件/gettimeofday.c】

#include <sys/time.h>
#include <time.h>
#include <stdio.h>
int main(void)  
{  
    char strtime[20] = {0};  
    time_t timep;  
    struct tm *p_tm;  
    timep = time(NULL);  
    p_tm = localtime(&timep);  
    strftime(strtime, sizeof(strtime), "%Y-%m-%d %H:%M:%S", p_tm);  
    return 0;  
}  

 settimeofday( )函数

表9 settimeofday()函数

这里写图片描述

功能:settimeofday( )把当前时间设成由tv指向的结构体数据。当前地区信息则设成tz指向的结构体数据。
【参见附件/gettimeofday.c】

#include <sys/time.h>
#include <time.h>
#include <stdio.h>
int main(void)  
{  
    char t_string[] = "2012-04-28 22:30:00";  
    struct tm time_tm;  
    struct timeval time_tv;  
    time_t timep;  
    int ret = 0;  
  
    sscanf(t_string, "%d-%d-%d %d:%d:%d", &time_tm.tm_year, &time_tm.tm_mon, &time_tm.tm_mday, &time_tm.tm_hour, &time_tm.tm_min, &time_tm.tm_sec);  
    time_tm.tm_year -= 1900;  
    time_tm.tm_mon -= 1;  
    time_tm.tm_wday = 0;  
    time_tm.tm_yday = 0;  
    time_tm.tm_isdst = 0;  
  
    timep = mktime(&time_tm);  
    time_tv.tv_sec = timep;  
    time_tv.tv_usec = 0;  
  
    ret = settimeofday(&time_tv, NULL);  
    if(ret != 0)  
    {  
        fprintf(stderr, "settimeofday failed\n");  
        return -1;  
    }  
    return 0;  
}

4.2进程相关命令解析

4.2.1 ps 查看系统中的进程

使用方式:ps [options] [–help]
说明:显示瞬间进程 (process) 的动态
参数:ps的参数非常多, 在此仅列出几个常用的参数并大略介绍含义
这里写图片描述
ps命令常用用法(方便查看系统进程)
1)ps a 显示现行终端机下的所有程序,包括其他用户的程序。
2)ps -A 显示所有进程。
3)ps c 列出程序时,显示每个程序真正的指令名称,而不包含路径,参数或常驻服务的标示。
4)ps -e 此参数的效果和指定"A"参数相同。
5)ps e 列出程序时,显示每个程序所使用的环境变量。
6)ps f 用ASCII字符显示树状结构,表达程序间的相互关系。
7)ps -H 显示树状结构,表示程序间的相互关系。
8)ps -N 显示所有的程序,除了执行ps指令终端机下的程序之外。
9)ps s 采用程序信号的格式显示程序状况。
10)ps S 列出程序时,包括已中断的子程序资料。
11)ps -t<终端机编号>  指定终端机编号,并列出属于该终端机的程序的状况。
12)ps u  以用户为主的格式来显示程序状况。
13)ps x  显示所有程序,不以终端机来区分。

4.2.2 top 动态显示系统中的进程

top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定。
这里写图片描述
统计信息区前五行是系统整体的统计信息。

  1. 第一行是任务队列信息
  2. 第二、三行为进程和CPU的信息
  3. 第四五行为内存信息。

4.2.3 & 将程序放到后台运行

这里写图片描述

4.2.4 jobs查看当前后台运行程序

这里运行的正是刚才使用&命令后正在执行的后台程序;
其中 [1] 为 jobnumber;
state 显示以下值之一(在 POSIX 的语言环境下):
Running 表示此作业没有被信号挂起并没有退出。
Done 表示此作业已经完成并返回退出状态 0。
Done (code) 表示此作业已经正常完成和退出并返回指定的非零退出状态码。这个代码用一个十进制数来表示。
Stopped 表示此作业已经挂起。
Stopped (SIGTSTP) 表示 SIGTSTP 信号挂起作业。
Stopped (SIGSTOP) 表示 SIGSTOP 信号挂起作业。
Stopped (SIGTTIN) 表示 SIGTTIN 信号挂起作业。
Stopped (SIGTTOU) 表示 SIGTTOU 信号挂起作业。

4.2.5 Ctrl + Z 将前台进程切换到后台执行

这里写图片描述
ping 192.168.5.100 命令使该进程一直在前台运行, 使用 Ctrl + Z 命令使其转换到后台运行;如果我们学了信号,就会知道 信号 SIGTSTP ,该信号是由Ctrl + Z 发出的,而SIGTSTP 用于暂停一个进程(挂起),所以这里可以看到该 job 的状态是 stopped ,说明其被切换到后台运行后 是被挂起的;这就要用到下面的 bg 命令;

4.2.6 bg 将挂起的进程在后台执行

使用方法 : bg + jobnumber(作业号)
这里写图片描述
可以看到 作业3在后台stat 为 runnig 。

4.2.7 fg 把后台运行的进程放到前台运2

这里写图片描述

本章参考代码

点击进入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bruceoxl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值