一、进程和线程
基础概念网上都有,面试的时候关于概念只要清楚一下几点
更多概念(有一个火车也挺形象)可以看看知乎大佬是这么说的
进程(处理器资源的基本单元)等于是cpu给你分配资源,不干活,相当于仓库。线程(任务执行的最小单位)就是干活。
一个进程里面至少一个线程,线程是依赖于进程上的,相当于干活的人必须在仓库里干活。
同一个进程里的线程是可以共同访问这个进程的资源的(涉及到资源访问冲突的问题以及解决方法-互斥锁)
2.5 C语言互斥锁使用方式(死锁及解决方法)
pthread_mutex Lock = PTHREAD_MUTEX_INITIALIZER;//声明锁 全局变量
pthread_mutex_init(&Lock,NULL);//初始化锁
pthread_mutex_lock(&Lock);//上锁
pthread_mutex_unlock(&Lock);//解锁
//举例
void func_a(){
int cnt=0;
while(cnt<5){
pthread_mutex_lock(&Lock);//判断是否上锁
printf("a\n");
cnt++;
pthread_mutex_unlock(&Lock);//解锁
}
}
void func_b(){
int cnt=0;
while(cnt<5){
pthread_mutex_lock(&Lock);//判断是否上锁
printf("b\n");
cnt++;
pthread_mutex_unlock(&Lock);//解锁
}
}
int main(){
pthread_mutex_init(&Lock,NULL);//初始化锁
pthread_t thread_a;//创建a线程ID
pthread_create(&thread_a, NULL, (void *)func_a, NULL);//创建线程
pthread_detach(thread_a);//线程结束后 资源自动回收
pthread_t thread_b;//创建b线程ID
pthread_create(&thread_b, NULL, (void *)func_b, NULL);//创建线程
pthread_detach(thread_b);//线程结束后 资源自动回收
while(1);
}
更多的还有线程的唤醒与等待(pthead_cond_init, pthread_cond_signal, pthread_cond_wait),就是线程在访问锁住资源的时候开始等待,资源一释放就唤醒开始工作,防止资源再次被锁住,不过问的不多。
- C语言创建及销毁线程的方式
pthread_t thread_ID;//创建线程ID
pthread_create(&thread_ID, NULL, (void *)function, NULL);//创建线程 对应到函数function
pthread_detach(thread_ID);//线程资源回收
pthread_exit(thread_ID);//终止线程
线程收尸这里涉及到pthread_detach与pthread_join的区别,就是一个结束了自动回收线程占有的资源,一个手动释放线程占有的资源,详见这里。不过这个面试问的也不多。
- C语言创建及销毁进程的方式(这里我也不是很懂 如果问父进程和子进程一些资源回收问题 就直接说自己在子进程创建上涉猎不多 只直到进程间的一些通信方式)
fork();//创建子进程
getpid();//获得当前pid
getppid();//获取父进程PID
execv();//进程中加载可执行文件
exit();//终结进程
\我这里进程间通信基本都说是用的套接字通信(套接字就是socket) 就是一个进程作为客户端,一个进程作为服务器,通过TCP/IP进行通信,顺便引导一波,说一下TCP握手,显示你对网络通信有基本了解。
- 进程的一些状态,只需要掌握就绪、运行和阻塞三个基本状态即可,详细可以了解三个状态的原因以及部分其他状态
二、开发与调试
- 首先得知道平时上层应用的开发工具
c语言开发:gcc(面向linux的c语言开发工具), arm-linux-gcc(面向arm平台的c语言开发工具)
c++开发:g++(面向linux的c++开发工具), arm-linux-g++(面向arm平台的c++开发工具)
通常开发流程:
//在linux环境(ubuntu)下编写好c文件 以hello.c为例
arm-linux-gcc -o hello hello.c//运行arm-linux-gcc
//其中-o表示输出(output) 输出可执行文件hello 其中源文件为hello.c
//里面就涉及到了文件生成四步骤:预处理、编译、汇编和连接
//将hello文件移植到arm平台(arm-linux) 执行即可
./hello //执行二进制文件 显示hello world
//在面向大工程 多文件编译时 需要编写makefile文件 执行多条gcc语句(批处理)
在出现bug时,通常通过printf直接输出变量信息或者gdb断点调试,以gdb调试为例
GDB调试流程:
//在linux环境(ubuntu)下编写好c文件 以hello.c为例
arm-linux-gcc -g -o hello hello.c//运行arm-linux-gcc
//这里-g表示带有gdb调试功能选项的可执行文件输出
gdb hello//通过gdb工具直接运行hello可执行文件
//gdb常用语句
//break(简写 b) :格式 b 行号,在某行设置断点
//run(简写 r) :运行程序直到遇到 结束或者遇到断点等待下一个命令;
//continue、step、next : 均为首字母 c, s, n
三、通信模块
基础概念要知道常用的通信模块:
I2C、SPI以及USB因为用的不多,所以只要了解他们的工作方式还有同步异步就可以
UART因为用的多,要清楚基本的信息,例如停止位、校验位还有中断是单字节接收,一般的波特率设置以及波特率的意义都要清楚。然后面试官一般就会开始问你中断的一些问题,设置中断要注意什么,中断流程之类的。
网口只要知道上面说的套接字通信方式即可,一般工控ARM-LINUX会设有两个网口,一个用于外网传输,一个用于本地配置
中断流程
1.根据响应的中断源的中断优先级, 使相应的优先级状态触发器置1;
2.把当前程序计数器PC的内容压入堆栈,保护断点,寻找中断源;
3.执行硬件中断服务子程序调用;
4.清除相应的中断请求标志位(串行口中断请求标志RI和TI除外);
5.把被响应的中断源所对应的中断服务程序的入口地址(中断矢量)送入PC, 从而转入相应的中断服务程序。
6.中断返回,程序返回断点处继续执行。
ISR(中断服务处理要求)
1、ISR不能有返回值 ;
2、ISR不能传递参数;
3、ISR应该是短而高效的,在ISR中做浮点运算是不明智的;
4、ISR中不应该有重入和性能上的问题,因此不应该在中断函数中使用pintf()函数。
四、其他
零散知识
1.带操作系统和不带操作系统的区别有哪些(linux、ucos与单纯的stm32以及51的区别)
2.什么时候多线程好一点,什么时候多进程好一点
3.知道read函数的具体实现流程吗
4.用户态和内核态切换的方式有哪几种
5.简单说一下uboot启动流程把
6.为什么uboot启动需要关闭cache