文章目录
- 前言
- 一、进程&线程
- 1、异步 IO 和同步 IO 区别?
- 2、进程间通信方式?
- 3、进程的地址空间模型?
- 4、进程的五种状态分别是?
- 5、子进程从父进程继承的资源有哪些?
- 6、什么是进程上下文、中断上下文?
- 7、如何防止僵尸进程过多导致系统空间爆满?
- 8、/proc目录下,以数字命名的目录表示什么?
- 9、进程和线程有什么区别?
- 10、什么时候用多进程?什么时候用多线程?
- 11、线程可以独立运行吗?一个线程崩溃会导致整个进程崩溃吗?
- 12、写出下列线程、互斥锁、信号量相关代码。
- 13、线程间通信和同步方式有哪些?
- 14、如何防止同时产生大量的线程?
- 16、互斥锁与信号量的区别?
- 17、孤儿进程是什么?
前言
记录一些招聘公司在招聘嵌入式软件岗位时的一些问题,此文为第八篇。
一、进程&线程
1、异步 IO 和同步 IO 区别?
答:如果是同步 IO,当一个 IO 操作执行时,应用程序必须等待,直到此 IO 执行完。相反,异步 IO 操作在后台运行,IO 操作和应用程序可以同时运行,提高系统性能,提高 IO 流量。
解读:在同步文件 IO 中,线程启动一个 IO 操作然后就立即进入等待状态,直到 IO 操作完成后才醒来继续执行。而异步文件 IO 中,线程发送一个 IO 请求到内核,然后继续处理其他事情,内核完成 IO 请求后,将会通知线程 IO 操作完成了。
2、进程间通信方式?
3、进程的地址空间模型?
4、进程的五种状态分别是?
- 就绪态:所有运行条件已就绪,只要得到了CPU时间就可运行。
- 运行态:得到CPU时间正在运行。
- 僵尸态:进程已经结束了但父进程还没来得及回收。
- 等待态:包括浅度睡眠跟深度睡眠。进程在等待某种条件,条件成熟后即进入就绪态。浅度睡眠时进程可以被信号唤醒,但深度睡眠时必须等到条件成熟后才能结束睡眠状态。
- 暂停态:暂时停止参与CPU调度(即使条件成熟),可以恢复。
5、子进程从父进程继承的资源有哪些?
答:子进程继承父进程的绝大部分资源,包括堆栈、内存、用户号和组号、打开的文件描述符、当前工作目录、根目录。
6、什么是进程上下文、中断上下文?
- 进程上文:是指进程由用户态切换到内核态时需要保存用户态时CPU寄存器中的值,进程状态以及堆栈上的内容。即保存当前进程的状态,以便再次执行该进程时,能够恢复切换时的状态,继续执行。
- 进程下文:是指切换到内核态后执行的程序,即进程运行在内核空间的部分。
- 中断上文:硬件通过中断触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。中断上文可以看作硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被中断的进程环境)。
- 中断下文:执行在内核空间的中断服务程序。
7、如何防止僵尸进程过多导致系统空间爆满?
答:每当子进程退出,父进程都会收到 SIGCHLD 信号,故可在父进程中设置 SIGCHLD 信号的捕获函数,在捕获函数中回收子进程。
void handler(int sig)
{
int status;
if(waitpid(-1, &status, WNOHANG) >= 0)
{
printf("child is die\n");
}
}
int main()
{
signal(SIGCHLD, handler);
int pid = fork();
if(pid > 0) //父进程循环等待
{
while(1)
{
sleep(2);
}
}
else if(0 == pid)
{ //子进程说自己die后就结束生命周期,之后父进程就收到SIGCHLD
//信号调用handler函数接收结束子进程,打印child is die。
printf("i am child, i die\n");
exit(0);
}
}
解读:
- 僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。
- 可用 top 命令查看僵尸进程的数量(zombie),也可用 ps -aux | grep Z(僵尸进程的状态显示为Z)来查看僵尸进程的 PID 等信息。
8、/proc目录下,以数字命名的目录表示什么?
以数字命名的目录表示当前一个运行的进程,目录名即为进程PID,其内的目录和文件给出了一些关于该进程的信息。
9、进程和线程有什么区别?
- 进程是系统中程序执行和资源分配的基本单位,线程是 CPU 调度的基本单位。
- 一个进程个拥有多个线程,线程可以访问其所属进程地址空间和系统资源(数据段、已经打开的文件、I/O设备等),同时也拥有自己的堆栈。
- 同一进程中的多个线程可以共享同一地址空间,因此它们之间的通信实现也比较简单,而且切换开销小、创建和消亡的开销也小。而进程间的通信则比较麻烦,而且进程切换开销、进程创建和消亡的开销也比较大。
10、什么时候用多进程?什么时候用多线程?
- 程序的安全性、稳定性要求较高时用多进程。
- 需要频繁通信/切换程序/创建跟销毁程序时用多线程。
11、线程可以独立运行吗?一个线程崩溃会导致整个进程崩溃吗?
答:
- 线程不能独立运行,但一个线程崩溃不一定导致整个进程崩溃。
解读:
- 线程属于进程,线程的运行需要依赖进程的地址空间和系统资源。
- 线程崩溃的本质就是内存出错,若出错的内存没有被其他线程访问,则不会导致其他线程出错,也就不会导致进程崩溃。
12、写出下列线程、互斥锁、信号量相关代码。
13、线程间通信和同步方式有哪些?
信号、信号量、互斥锁、条件变量、自旋锁、读写锁。
14、如何防止同时产生大量的线程?
- 方法是使用线程池。
- 线程池可以提高调度效率和限制资源使用,线程池中的线程达到最大数时,其他线程就会排队等候。
16、互斥锁与信号量的区别?
- 信号量用于线程同步,互斥锁用于线程互斥。
- 信号量可以为非负整数,可以实现多个同类资源的多线程同步;互斥锁只能为0/1,只能用于一个资源的互斥访问。
- 信号量可以由一个线程释放,另一个线程得到;互斥锁的加锁和解锁必须由同一线程分别对应使用,且多个线程使用多个互斥锁必须注意统一顺序,否则可能造成死锁。
17、孤儿进程是什么?
- 父进程先于子进程结束,此时子进程成为一个孤儿进程。
- Linux系统规定:所有孤儿进程都成为一个特殊进程(进程1,也就是init进程)的子进程。
我的qq:2442391036,欢迎交流!