基本信息
1、程序
程序是一个存储在磁盘某个目录上的可执行文件,内核使用exec函数将程序读入内存,并执行程序。
2、进程
进程是程序执行的实例 ,用于控制进程的有3个主要的函数。 fork() 、 exec() 、 waitpid()
exec函数有7种变体。但它们总称为exec函数。
3、线程
通常情况下,一个进程只有一个控制线程。
也可以多个控制线程可以充分利用多处理器系统的并行能力。
一个进程内所有的线程共享同一地址空间、文件描述符、栈以及与进程相关属性。因为它们能访问同一存储区,所以各线程在访问共享数据时需要采取同步措施以避免不一致性。
与进程类似,线程也用ID 标识,但线程的ID 只在它所属的进程内起作用。我们可以使用改线程ID 引用它。进行处理。线程ID 只在它所属的进程内有意义。
出错处理
在C语言头文件 <errno.h> 中定义了出错的状态码和出错原因
在Ubuntu 系统中, 头文件 errno.h 位于 /usr/include/asm-generic/errno.h
打开errno.h头文件,可以看到变量对应的出错情况。下图是截取的部分宏。在百度百科里也有相关说明。
百度百科部分内容
在C语言中定义了两个标准函数用来输出错误出错消息。
//1
#include <string.h>
char * strerror(int errnum);
errnum 通常是errno 的值 ,strerror映射为对应出错的消息。并返回指向此字符串的指针。
//2
#include <stdio.h>
void perror(const char *msg);
perror 是根据errno 的当前 值进行输出对应的出错消息。
输出结果为 先输出 msg 指向的字符串 ,然后冒号 之后出错的消息,最后换行符。
1 #include <stdio.h>
2 #include <errno.h>
3 #include <string.h>
4 int main(int argc, char *argv[])
5 {
6 fprintf(stderr,"EACCES: %s\n", strerror(EACCES));
7 errno = 39; //或者 errno = ENOTEMPTY
8 perror(argv[0]);
9 return 0;
10 }
输出结果为:
可根据输出来判断程序出错的原因,及时进行处理,排除故障。或者对可能的出错进行判断,防止程序崩溃,提高程序的健壮性。
用户标识
用户ID,是用来标识各个不同的用户的。
组ID , 用来标识用户的属组。
组文件将组名 映射为 组ID 可以在 /etc/group 中查询。
利用程序获取用户ID 和组ID
包含头文件 <unisted.h>
getuid() 获取用户ID getgid() 获取用户组ID。
#include <unisted.h>
int main()
{
printf("%d, %d\n", getuid(), getgid());
return 0;
}
信号
信号用于通知 进程发生了某种情况
进程有以下三种处理信号的方式
1、忽略信号。
2、按系统默认方式处理。终止进程。
3、提供一个函数,信号发生时调用函数。
终端键盘上有两种产生信号的方法。 中断键(CRTl + C ) 或者退出键(CTRL + \ ) 它们被用于中断当前运行的进程。
也可使使用kill 函数。在一个进程里向另一个进程发送一个信号。
为了捕捉到信号,程序需要调用signal 函数 , 其中指定了当产生SIGINT 信号时,要调用的函数名字。
if (signal(SIGINT, sig_int) == SIG_ERR)
{
printf ("signal error\n");
}
在程序运行时使用键盘输入 CTRL + c 进程使用signal 函数接受到SIGINT 后没有按照默认方式结束进程。而是使用sig_int 函数去处理。由于除于循环之中,所以无法通过CTRL + c 关闭程序。
需要包含 头文件 #include <signal.h>
图片来源于博客 https://blog.csdn.net/fengbingchun/article/details/92074191
时间值
1、日历时间
日历时间从1970 年 1号 0 点开始,以秒计算。可以通过时区得到本地时间 使用tm 结构体可以获取 秒数 对应的详细时间。
2、进程时间,也被称为CPU 时间 。用以度量进程使用的中央处理器资源。
当度量一个进程执行的时间时,Unix 系统为一个进程维护了3个进程时间值。
a、时钟时间
b、用户CPU时间
c、系统CPU时间
时钟时间又称为墙上时钟时间,它是进程运行的时间总量,其值与系统中同时运行的进程数有关。
用户CPU时间是执行用户指令所用的时间量。
系统CPU时间是为该进程执行内核程序所经历的时间。为了获取一个进程的进程时间可以使用shell 命令 time
$ time date
第一章相关代码
使用相关头文件
#include <unistd.h> fork() execlp () 函数
#include <stdlib.h> exit()
#include <wait.h> waitpid()函数头文件
#include <errno.h> errno 变量
1 #include <stdio.h>
2 #include <wait.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <signal.h>
7 static void sig_int()
8 {
9 printf("sig_int error\n");
10 }
11
12
13 int main()
14 {
15
16 char buf[200];
17 pid_t pid;
18 int status;
19
>> 20 if (signal(SIGINT, sig_int) == SIG_ERR)
21 printf ("signal error\n");
22
23 printf("%%");
24
25 while (fgets(buf, 200, stdin) != NULL)
26 {
27 if (buf[strlen(buf) -1] == '\n')
28 buf[strlen(buf) - 1] = 0;
29
30
31 if ((pid = fork()) < 0)
32 {
33 printf("fork error\n");
34 } else if (pid == 0)
35 {
36 execlp(buf, buf, (char*)0);
37 printf("couldn`t execute: %s", buf);
38 exit(127);
39 }
40 if ((pid = waitpid(pid,&status, 0)) < 0)
41 printf("waitpid error");
42 printf("%%");
43 }
44 return 0;
45 }
注意 程序运行后,无法使用 CTRL + c 关闭。因为会signal 会捕获这个信号,并调用sig_int 函数处理。不会以默认方式退出。可以使用 CTRL + \ 退出。