一、异常控制流
- 事件发生情况:
- 与当前指令的执行直接相关。例如:发生虚拟内存缺页、算术溢出、除以零
- 与当前指令的执行无关。例如:I/O请求完成
- 事件发生时:调用异常处理程序
处理完成后:
- 异常的种类:
- 异步异常是由处理器外部的I/O设备中的事件产生的.
- 同步异常是执行一条指令的直接产物。
进程提供给应用程序的关键抽象:
获取进程ID
- pid_t getpid(void);//返回调用进程的PID
- pid_t getppid(void);//返回父进程的PID
创建进程
- pid_t fork(void);
- 子进程返回0,父进程返回子进程的PID,如果出错,则为-1
fork特点
- 调用一次,返回两次
- 并发执行
- 相同但是独立的地址空间
- 共享文件
进程三状态
- 运行。
- 停止。收到停止信号,就停止;收到继续信号,就再次开始运行。
- 终止。
- (1)收到一个信号,该信号的默认行为是终止进程
- (2)从主程序返回
- (3)调用exit函数
传送一个信号到目的进程
- 发送信号:
- 内核检测到一个系统事件,例如:除零错误或者子进程终止
- 一个进程调用了kill函数
- 接收信号
二、数组指针和指针数组
指针数组(元素为指针的数组)int *p1[5];
数组指针(指向数组的指针)int (*p2)[5]
三、函数指针和指针函数
指针函数(返回值为指针的函数)
#include <iostream>
using namespace std;
int *GetNum(int x); //指针函数声明形式
void main(void)
{
cout << "===============start================" << endl;
int num;
cout << "Please enter the number between 0 and 6: ";
cin >> num;
cout << "result is:" << *GetNum(num) << endl; //输出返回地址块中的值
system("pause");
}
int *GetNum(int x) {
static int num[] = { 0,1,2,3,4,5,6 };
return &num[x]; //返回一个地址
}
函数指针(指向函数的指针)
#include <iostream>
using namespace std;
int max(int a, int b) {
return a>b ? a : b;
}
void main(void)
{
cout << "===========start===========" << endl;
int(*func)(int, int); //定义一个指向该函数形式的指针变量
func = max;
int a, b;
cout << "Please enter two numbers:";
cin >> a >> b;
cout << "max=" << (*func)(a, b) << endl; //运用指针变量调用函数
cout << "max=" << max(a, b) << endl; //使用原函数调用
cout << "max=" << func(a, b) << endl; //使用函数指针名调用,func = max
system("pause");
}
四、遇到的问题及解决方法
- 问题1:编译C程序时,出现
致命错误:csapp.h:没有那个文件或目录
解决方法1:在编译时加上
-I参数 头文件所在目录
问题2:编译带有自定义头文件的C程序,在加上头文件路径后,出现
undefined reference to Fork
解决方法2:在编译带有自定义的头文件时,要先对该头文件里面所描述的方法生成静态链接库/动态链接库,然后在编译时调用该链接库。
问题3:由于csapp.h头文件中,还定义了一些线程方法,所以在进行编译时还应该加上-lpthread参数
- 解决方法:使用命令
man -k thread
和man 3 pthread_join
查看编译含有线程函数所需要添加的参数
五、心得体会
- 前几周比较忙,落下了较多的课程,老师课上测试与课上讲解也都云里雾里,这种感觉真的很差。
- 为了拨开云雾见天明,我花了大量的周末时间,终于补上了落下的课程,许多之前的迷惑也都解开了。
- 感想就是一定要一步一个脚印,不要落下,否则最后狂补真的很累。