面试总结(c++)
程序员文章站
2022-03-07 22:50:07
...
一、进程与线程有什么区别?各自的应用场景分别是什么?
进程:进程是系统进行资源分配的基本单位。所以与该进程有关的资源,都被记录在进程控制块(PCB)中。以表示该进程拥有这些资源或者正在使用它们。
线程:windows中的线程与linux中的线程其实还是有比较大的差别的,但是我们不关心。线程,也被称为轻量级进程(lwp),是程序执行流的最小单元,是进程中的一个实体,是被系统独立调度和分派的基本单位。
线程执行开销小,但是不利于资源的管理和保护。适合在多核机器上运行。
进程执行开销大,但是能够很好的进行资源管理和保护。
对资源的管理和保护要求高,不限制开销和效率时,使用多进程。
要求效率高,频繁进行上下文切换时,资源的保护管理要求不是很高时,使用多线程。
多线程和多线程对比:
数据共享、同步:多进程数据共享复杂,需要用IPC;数据是分开的,同步简单。 多线程因为共享进程数据,数据共享简单,但是同时导致同步复杂。
内存、cpu:多进程占用内存多,切换复杂,cpu利用率低。 多线程占用内存少,切换简单,cpu利用率高。
创建销毁、切换:多进程创建销毁、切换复杂,速度慢。 多线程创建销毁、切换简单,速度很快。
二、进程间通信方式有哪些?以及优缺点
管道,FIFO,消息队列,信号量,共享内存,UNXI域套接字,套接字
1.管道
管道是一种古老的IPC通信方式:半双工,即不能同时在两个方向上进行传输。只能在父子进程间。
int pipe(int pipefd[2], int flags);
示例:
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <wait.h>
using namespace std;
int main()
{
pid_t pid;
int fd[2];
int ret = pipe(fd);
int status = -1;
if(ret == -1)
{
perror("pipe error");
exit(-1);
}
cout << "开始" << endl;
pid = fork();
if(pid == -1)
{
perror("fork error");
exit(-1);
}
if(pid == 0) //子进程 读数据
{
//将写端关闭
//为保证写的时候,读操作已经完成了,所以儿子先睡一下
sleep(2);
close(fd[1]);
char buf[1024];
int ret = read(fd[0], buf, sizeof(buf));
if(ret == -1)
{
perror("child read error");
exit(-1);
}
cout << buf << endl;
}
else //父进程 写数据
{
//将读端关闭
close(fd[0]);
char hh[1024] = "我是数据";
int ret = write(fd[1], hh, sizeof(hh));
if(ret == -1)
{
perror("parent write error");
exit(-1);
}
//回收子进程
wait(&status);
}
cout << "结束" << endl;
return 0;
}
2.FIFO
int mkfifo(const char* path, mode_t mode);
3.消息队列