1.linux中把分区和目录对应的过程叫做(挂载)
2.信号是在软件层次上对(中断)机制的一种模拟, 是一种异步通信方式。
3.用GCC编译过程可以被细分为四个阶段:(预处理、编译、汇编和链接)
4.编译有线程的文件要加(-pthread)参数。
5.父进程等待子进程的结束,可以使用的函数是(wait())和(waitpid())
6.linux主要有两个信号安装函数,分别是什么?(signaction)、(signal)
7.Linux操作系统内核由(c语言和汇编语言)编写完成。
8.目录(/boot)下存放linux操作系统启动时所要用到的程序
9.Linux 系统的设备文件分为三类?(字符设备、块设备和网络设备)
10.Linux 中采用“一对一”的线程机制,也就是一个用户线程对应一个(内核线程)
11.vim三种模式:在命令模式下按下(:(英文冒号))就进入了底线命令模式。
12.Vim的三种模式:(命令模式 插入模式 底行模式)
13.标准I/O提供了三种类型的缓冲,分别是?(全缓冲,行缓冲,不带缓冲)
14.linux文件系统由四部分组成(内核、shell、文件系统和应用程序)用于存放文件的控制信息。
15.一个完整的信号生命周期包含4个重要的事件,这4个重要事件分别是?(信号诞生、信号在进程中注册、信号在进程中注销、信号处理函数执行完毕)
16.互斥锁只有两种状态,即?(上锁( lock )和解锁( unlock ))
17.线程本身调用(pthread_exit)函数可以退出线程。
18.向消息队列发送消息的函数是(msgsnd)
19.(fcntl)系统调用可以根据文件描述符来操作文件特性。
20.Valgrind包括很多工具,(Memcheck)是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,(Cachegrind)是主要用来检查程序中缓存使用出现的问题。
21.信号发送函数中, (alarm)和(setitimer())用于设置定时器,当计时时间到达时,向进程发送SIGALRM信号。
22.在标准IO库中,rewind函数作用?(将文件内部的位置指针重新指向一个流(数据流/文件)的开头)
23.c语言中没有明确给定初值的全局变量和静态变量存放在哪儿?(全局存储区(静态存储区))
24.函数geteuid()用于得到进程的? (用户有效 UID 值)
25.当一个线程的属性设置为(分离状态),该线程结束时立即释放它所占有的系统资源。
26.以下哪种方式属于异常终止一个进程(D接到一个信号并终止)
27.下列命令哪个是创建线程私有数据命令()(pthread_key_create())
28.下面哪种通信方式适用于不同机器之间的进程通信。(套接字)
29.linux中通过调用waitpid()函数得到进程的退出信息,该函数原型为pid_t waitpid(pid_t pid, int *status, int options);当第一个参数pid取值为-1时,表示(等待任一子进程退出,相当于 wait())
30.Linux环境中使用kill函数向进程或进程组发送信号。Kill函数原型为int kill(pid_t pid, int signo);当第一个31.参数pid>0时,表示(发送信号给进程ID为pid的进程)
32.共享主存基本操作(shmat())将共享主存区映射到进程虚拟地址空间
33.lseek(fd,位移数,whence):设置文件偏移量
34.文件描述符的数据类型:int
35.创建目录:mkdir()
36.命令行有什么函数提供:shell
37.getpid()获取子进程id getppid()获取父进程id
38.getuid()获取用户id geteuid()获取有效用户id
39.更改目录:cd ;查看当前所在的目录位置: pwd;查看目录下的文件: ls;修改文件权限:chmod;查看进程:ps
40.进程中不能忽略的两个信号?(SIGSTOP和SIGKILL)
41.UDP,TCP属于(传输层)协议。
42.移动指针lseek函数的参数:(lseek(int fd ,_off_t offset , int whence))
43.一个进程是 ( PCB 结构与程序和数据的组合)
44.一个进程调用 wait 或 waitpid 函数,可能产生 3 中情况,下列不属于这 3 种情况的是 (如果该进程没有子进程,立即返回,返回值为 0)
45.程序和进程是两个不同的概念,以下不能描述这个观点的是 (同一个程序运行 10 次,产生的是同一个进程)
46.哪种进程之间的通信,数据不可以重复读(fifo、 管道)
47.下述是Linux下多线程编程常用的pthread库提供的函数名和意义,说法不正确的是?(pthread_exit杀死一个线程)
48.对线程函数来说,说法正确的是:(pthread_create中参数arg是传递给start_routine函数的参数)
49.对互斥锁及条件变量说法不正确的是:(在使用条件变量时,互斥锁会失去作用,所以是否有互斥锁关系不重要)
50.以下说明正确的是:(线程是一个独立的指令流,是在进程中被创建的,随进程的关闭而关闭)
51.线程A SendMessage给线程B,线程B处理该消息时又SendMessage给线程A,会出现:(继承执行)
52.linux文件系统通常由四部分组成:引导块,超级块,索引节点和 (数据块)
53.任何进程在运行时默认打开的三个流对象,都有相应的文件描述符,标准文件描述符定义标准输入设备的值为(0)
54.系统调用的函数原型int open(const char *pathname, int flags),flag值中(O_TRUNC)表示若文件存在且为只读或只写成功打开,则将长度截为0。
55.使用下列函数调用int fcntl(int fd, int cmd);来实现文件描述符的复制,cmd参数应使用哪一个?(F_DUPFD)
56.获取目录的系统调用函数为(getcwd())
57.linux 文件系统由四部分组成,(超级块)用于存放文件的控制信息。
58.使用 gdb 调试程序时,next 和 step 命令的作用?(next:单步运行,不进入函数内部; setp:单步运行,进入函数内部)
59.返回调用进程的进程标识号的系统函数是(getpid)
60.进程初始化数据区:全局初始化数据区/静态数据区
61.进程的堆区:用于动态内存分配。一般由程序员分配和释放,若程序员不释放,程序结束时由 OS 回收。
62. Linux 文件系统中的块有(根据块使用的不同):引导块、超级块、Inode 块、数据块。 控制信息、文件基本属性等是 Inode 节点,为文件系统索引。存放数据的为数据块。超级块中含有文件系统的基本信息,如块大小、指向空间 inode 和数据块的指针等相关信息。
63.进程运行时默认打开的标准对象:标准输入设备 stdin、标准输出设备 stdout、标准错误 输出设备 stderror
64.修改文件权限命令:chmod、chgrp、chown。
65.文件描述符为?整型。对于用户空间来说,任何打开的文件都将分配一个唯一非负整数, 用于标识该打开文件,该值即文件描述符,为一个大于等于 0 的整数。
66.权限的值?读:4 写:2 执行:1 注意:前三位为用户的权限,再三位为所属组的权 限,再三位为其他用户的权限。
67.获取文件属性,是否穿透?stat 函数具有穿透能力,能够穿透链接文件;而 lstat 函数不 具有穿透能力,不穿透链接文件,文件类型还为链接文件。
68. opendir 函数:打开一个目录,返回一个目录流指针。参数为欲打开目录的名称(路径)。
mkdir 函数:第一个参数是欲创建的目录文件路径,第二个参数是创建目录的权限。
69. fcntl 函数:修改某个文件描述符的特殊属性
70.创建硬链接的系统调用:link()
71.接受消息队列的函数 msgrcv()
72.自己退出线程的函数:pthread_exit();被取消线程运行:pthread_cancle()
73.互斥锁、条件变量、读写锁的初始化:互斥锁的初始化:pthread_mutex_init() 条件变量的初始化:pthread_cond_init() 读写锁的初始化:pthread_rwlock_init()
74.读写锁:非阻塞的加锁解锁和阻塞的加锁解锁。
堵塞的方式申请读锁:pthread_rwlock_rdlock()
非堵塞的方式申请读锁:pthread_rwlock_tryrdlock()
堵塞方式申请写锁:pthread_rwlock_wrlock()
非堵塞方式申请写锁:pthread_rwlock_trywrlock()
75.互斥锁的上锁函数是 pthread_mutex_lock(),非阻塞加 try; 解锁函数是 pthread_mutex_unlock()。
76.面向连接的编程:TCP;面向无连接的是:UDP
77.在不同主机间进行通讯的是:scoket 或者是套接字
78.三次握手:连接建立、数据传输、连接释放。
79.创建套接字的函数 scoket()
80.网络编程的常见函数:
监听网络函数:listen()
发起连接函数:connect()
接受连接函数:accept()
读写 scoket 对象:read()/write()
TCP 发送和接受数据:send()/recv()
关闭 scoket 对象:close()
81. Linux下获取文件属性函数: stat()
1.预处理,生成预编译文件(.i文件) Gcc –E hello.c –o hello.i
2.编译,生成汇编代码(.s文件): Gcc –S hello.i –o hello.s
3.汇编,生成目标文件(.o文件): Gcc –c hello.s –o hello.o
4.链接,生成可执行文件: Gcc hello.o –o hello
2.使用gdb调试程序时,next和step命令的作用?
step 就是单步执行,遇到子函数就进入并且继续单步执行;
next 是在单步执行时,在函数内遇到子函数时不会进入子函数内单步执行,而是将子函数整个执行完再停止,也就是把子函数整个作为一步
3.“i键”进入编译模式 “ctrl+v”进入可视模式 “ESC:”进入底行模式
y ##复制 c ##剪切 u ##撤销
d ##删除 p ##粘贴 ctrl+r ##恢复
4.pid_t fork() 返回值的意义?
若执行成功,父进程中将返回子进程(新创建的进程)的PID,类型为pid_t,
在子进程中将返回0,以区别父子进程
若执行失败,则在父进程中返回-1,错误原因存储在errno中
5. fork 和 vfork 的区别与联系
区别:
1.fork()用于创建一个新进程。由 fork()创建的子进程是父进程的副本。即子进程获取父进程数据空间,堆和栈的副本。父子进程之间不共享这些存储空间的部分。而vfork()创建的进程并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec (或exit) 于是也就不会存放该地址空间。相反,在子进程调用exec或exit之前,它在父进程的空间中进行。
2.vfork()与fork()另一个区别就是:vfork保证子进程先运行,在子进程调用exec或exit之后父进程才可能被调度运行。而fork创建的子进程和父进程的运行的先后顺序是没有保证的
3.联系:两者被调用一次,但是返回两次。两次返回的唯一区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程 ID。
6.父进程调用wait() 可能出现的三种情况?
当有子进程退出时wait返回子进程的pid并且获取到子进程的退出状态
当没有子进程退出时 父进程将阻塞等待子进程退出
当没有子进程时,wait返回-1,并且显示报错信息
7. wait 函数:调用 wait 函数的父亲进程将堵塞式等待任意一个子进程结束后,回收该子进程的内核进程资源。status参数用来接受子进程退出状态。返回值为子进程的 PID。
waitpid 函数,用来等待指定子进程结束。返回值为子进程的 PID。 第一个参数,大于 0 时,表示等待进程 PID 为该 PID 值的进程结束; 等于 0 时,表示等待与当前进程的进程组 PGID 一致的进程结束; 等于-1 时,与 wait 函数相同; 小于-1 时,表示等待进程组 PGID 是此值的绝对值的进程结束。 第二个参数用来接受等待进程的结束状态。
8. 在进程中,return和exit的区别?
1.return是函数的退出(返回),返回值确定;exit()是进程的退出,可以自己设置返回值并结束。
2.return是语言级别的,它表示了调用堆栈的返回,会弹栈;而exit是系统调用级别的,它表示一个进程的结束。
3.return是C语言提供的,exit是操作系统提供的。
4.在main函数里,return 0和exit(0)是一样的,子函数用return返回到上级函数调用的位置,而用exit会终止进程,调用exit时要调用一段终止处理程序,然后关闭所有I/O流。
5.exit和_exit就是用来正常终止一个进程的,主要区别是_exit会立刻进入内核,而exit先执行一些清除工作然后才进入内核。
9. 什么是孤儿进程?谁负责回收孤儿进程的内核空间资源?
孤儿进程:孤儿进程就是其在正常运行时,因父亲进程先退出而导致这个子进程被init进程收养的进程,即孤儿进程的父亲更改为init进程,该进程在孤儿进程退出后回收它的内核空间资源。
10. 僵尸进程是什么?如何消灭僵尸进程?
僵尸进程:如果子进程退出,但是父进程没有调用wait或waitpid获取子进程的状态信息,即该进程在内核空间的PCB没有释放,那么子进程的进程描述符pid仍然保存在系统中,那么该子进程叫做僵尸进程
利用kill函数杀死父进程,僵尸进程会被init进程收养,也可以通过调用wait()或waitpid()使其成为孤儿进程由操作系统回收其内核资源
11. 简述进程对可靠信号和不可靠信号的处理过程。
1.可靠信息是多个信号发送到进程的时候,收到的信号超过进程处理信号的速度的时候,这些还没有来的急处理的信号就会被操作系统会记录,所有的信号排入进程的队列,等进程有机会来处理的时候,依次再处理,信号不丢失,当进程解除屏蔽后,操作系统会捕获对等次数。
2.不可靠信号是指linux在SIGRTMIN实时信号之前的都叫不可靠信号,这里的不可靠主要是不支持信号队列,就是指多个信号发送到进程的时候,如果处理信号的速度不够,这些没来得及处理的信号就会被丢掉,仅仅留下一个信号。即如果进程在屏蔽某个信号时间内,其他进程多次发送同一个信号,不可靠信号只有一次未决记录,当进解除屏蔽后,该信号只会被捕获一次。
12. 简单介绍一下信号的定义及其分类
1.linux信号是一种进程间异步的通信机制,在实现上是一种软中断。信号可以导致一个正在运行的进程被异步打断,转而处理一个突发事件,只能够通过某些特定的方式来预防,或者说,当该异步事件发生时根据原来设定完成相应的函数。
2.信号是UNIX系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动。
3.信号是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等。
其中,0~31分为不可靠信号 32~63可靠信号。信号相关函数有信号安装函数sigaction()和信号发送函数sigqueue()等。
4.信号可分为两种:
①不可靠信号:
信号值小于SIGRTMIN(32号)
进程每次处理信号后,将信号响应函数设置为默认动作,需调用signal() 重新安装信号 ;
非实时信号都是不可靠信号,不支持排队,信号可能丢失;
② 可靠信号:
信号值介于SIGRTMIN和SIGRTMAX之间;
实时信号都是可靠信号,支持排队;
13. 简单介绍一下匿名管道及其特点。
1.匿名管道:是指用于连接一个读进程和一个写进程,以实现它们之间通信的共享文件,又称pipe文件,是一个只存在于内存的特殊文件,依赖于文件系统,它的生命周期随进程的结束而结束。
2.匿名管道创建在内核空间,是半双工的,只能一端写一端读,向一个方向流动,数据先进先出,数据被进程从管道读出后,在管道中该数据就不存在了,在通信结束后消失。
3.匿名管道用于进程之间通信,自身带同步机制,通常用于父子进程间通信,结构简单。
14. 解释一下有名管道和匿名管道的区别?
1.有名管道:也称为FIFO管道,是一种文件类型,在文件系统中可以查看到,其inode结点在磁盘上;
无名管道是无形的,在系统中没有实名,不能在文件系统中以任何方式看到,无名管道的 inode 结构不是在磁盘上存储的,而是临时生成的。
2.有名管道是由mkfifo函数创建的,打开用open函数;匿名管道是由pipe函数创建并打开的。
3.有名管道不需任何关系也可以通信;无名管道只能用于父子进程或兄弟进程之间的通信。
4.有名管道是一种双向通信管道,可以用读写模式打开有名管道,索引节点出现在系统目录树上而不是pipefs特殊文件系统中;匿名管道只是进程的一种资源,会随着进程的结束而被系统清除。
15.
线程的创建函数:pthread_create()
线程分离状态:.pthread_detach()
退出线程:pthread_exit()
取消线程:Pthread_cancel()
16. 线程与进程的区别
1.进程是资源分配的最小单位,线程是操作系统能够进行运算调度的最小单位,其所占资源较少,即程序执行的最小单位,线程也是进程的内部的一个执行序列, 可以看作是轻量化的进程.
2.进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段。而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多,因此进程拥有资源多,线程拥有资源少,进程间切换代价大,线程间切换代价小。
3.线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以管道等方式进行。
4.多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
17. GDB调试命令:
添加断点: break + 行数 (b 也行)
delete 断点号n:删除第n个断点
i b 查看断点信息
list:简记为 l , 查看文件源代码
run(简写r): 运行程序
continue(简写c) : 继续执行,到下一个断点停止
next(简写n) :执行一步
18. linux进程的结构有哪些:
代码段:代码段是用来存放可执行文件的操作指令,也就是说是它是可执行程序在内存中的镜像。
数据段:数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配的变量和全局变量。
堆(heap):堆是用于存放进程运行中被动态分配的内存段
栈:栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量
19.文件系统四部分:引导块,超级块,索引节点,数据区
超级块: 用于存放文件的控制信息。
引导块:在文件系统的开头,通常为一个扇区,其中存放引导程序,用于读入并启动操作系统;
超级块:用于记录文件系统的管理信息。特定的文件系统定义了特定的超级块;
inode区(索引节点):一个文件或目录占据一个索引节点。第一个索引节点是该文件系统的根节点。利用根节点,可以把一个文件系统挂在另一个文件系统的非叶节点上;
数据区:用于存放文件数据或者管理数据。
20. 进程和程序的区别?
1.程序是永存的;进程的存在是暂时的,是程序在数据集上的一次执行,有创建有撤销。
2.进程是程序及其数据在计算机上的一次运行活动,由程序、数据和PCB三部分组成,是一个动态的概念;而程序是一组有序的指令集和,是一种静态的概念。
3.进程具有并发性,而程序没有。
4.进程是竞争计算机资源的基本单位,程序不是。
5.进程和程序不是一一对应的:一个程序可对应多个进程,即多个进程可执行同一程序;一个进程可以执行一个或几个程序。
21. fcntl函数的功能:
1.复制一个已有的描述符,类似于dup函数功能。
2.获取/设置文件描述符标志。
3.获取/设置文件状态标志。
4.获取/设置一步I/O所有权。
5.获取/设置记录锁。
22. 列出linux的进程通信方式,简单描述?
1.管道:包括三种,普通管道,流管道,命名管道
2.信号量:是一个计数器,可以用来控制多个进程对共享资源的访问
3.消息队列:是消息的链表,存放在内核中并由消息队列标识符标识
4.信号:是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生
5.共享内存:是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问
6.套接字:是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信
23. 请简要描述signal()和sigaction()的区别
1.signal() 安装的信号不能向信号处理函数传递信息;sigaction() 可设置进程的信号掩码,安装的信号可以向信号处理函数传递信息。
2.signal在调用handler之前先把信号的handler指针恢复;sigaction调用之后不会恢复handler指针,直到再次调用sigaction修改handler指针。
3.signal在调用过程不支持信号block;sigaction调用后在handler调用之前会把屏蔽信号(屏蔽信号中自动默认包含传送的该信号)加入信号中,handler调用后会自动恢复信号到原先的值。
4.signal处理过程中不能提供阻塞某些信号的功能,sigaction可以阻止指定的信号和本身处理的信号,直到handler处理结束。
5. sigaction()是POSIX的信号接口,而signal()是标准的C的信号接口
6.Sigaction可以设置新的信号处理函数act,同时保留该信号原有的信号处理函数oldact
7. 相同点:都可以为指定的信号设置信号处理函数;共用同一个内核函数do_sigaction()
24.
向消息队列发送信号:msgsnd ()
接收队列的函数: msgrcv()
创建消息队列:msgget()
关闭消息队列:msgctl()
26. 简单说明信号的处理方式?
1.忽略信号:忽略此信号,大多数信号都可以采用这种方式进行处理,除了9( SIGKILL )和19(SIGSTOP )信号。
2.捕获信号:进程要通知内核在某种信号产生时,需要调用一个用户函数,在用户函数中,用户可以自己定义信号处理的方式,在Linux下我们不能捕捉SIGKILL信号和SIGSTOP信号。
3.执行默认动作(缺省):一般情况下是终止该进程。
27. 产生信号的方式?
1.来自键盘的信号
2.硬件异常产生信号
3.通过系统调用向进程发送信号
4.由软件异常等产生信号
28. 信号的生命周期
1.信号诞生:触发信号的事件发生(如检测到硬件异常、定时器超时以及调用信号发送函数kill()或sigqueue()等)。
2.信号在进程中注册:内核更新目标进程的数据结构,将信号加入进程的未决信号集,并将信号所携信息保存到某个sigqueue结构中。对实时信号,不管其是否已在进程中注册,都被再次注册;对非实时信号,若该信号已在进程中注册,则将其丢弃
3.信号在进程中注销:进程从核心空间返回用户空间时都检测是否有信号等待处理;若存在等待处理且未被阻塞的未决信号,则将其在未决信号链中占有的结构卸掉(对实时进程只删除sigqueue结构)
4.信号处理函数执行完毕:执行相应信号处理函数或改变目标进程的执行状态
29. osi 七层模型:应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
30.对硬连接和软连接的描述:
1.硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号。硬连接的作用是允许一个文件拥有多个有效路径名;软链接文件类似于Windows的快捷方式。它实际上是一个特殊的文件。在软连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。
2.硬链接和原来的文件共用一个inode节点。相当于加了个相同的文件,只是改了改名字。
31.
硬链接创建函数:link
删除硬链接函数:unlink
软连接创建函数:symlink
读取软连接中的内容所用的函数:readlink(文件名,读取到的空间,读取的大小)。
32. 中断的描述?
中断是指在CPU正常运行期间,由于内外部事件或由程序预先安排的事件引起的CPU暂时停止正在运行的程序,而转到该内部或外部事件或预先安排的事件服务的程序中去,服务完毕后再返回去继续运行被暂时中断的程序
33. 共享内存:
shmget()函数用来创建共享内存
shmat()函数用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间
shmdt()函数用于将共享内存从当前进程中分离
shmctl()函数用来控制共享内存
34. 对互斥锁的理解?
互斥锁是用一种简单的加锁方法来控制对共享资源的操作,主要用于实现内核中的互斥访问功能,是一种用于多线程编程中,防止两条线程同时对同一公共资源进行读写的机制。
35.
初始化互斥锁函数:pthread_mutex_init
也可以用宏PTHREAD_MUTEX_INTIALIZER 初始化静态分配的互斥锁
上锁函数:int pthread_mutex_lock()以阻塞的方式申请互斥锁
int pthread_mutex_trylock()以非阻塞的方式申请互斥锁
解锁函数:pthread_mutex_unlock()释放操作只能由占有该互斥锁的线程完成。
36. TCP与UDP的区别?
1.TCP面向连接,UDP是面向无连接的
2.TCP提供可靠的服务,UDP尽最大努力交付,但不保证可靠交付
3.TCP传输效率相对较低,UDP传输效率高
4.TCP连接只能是点到点、一对一的,UDP支持一对一,一对多,多对一
37. TCP的三次握手?
第一次握手:建立连接时,客户端发送SYN包到服务器,并进入SYN_SENT状态,等待服务器确认;
第二次握手:服务器收到SYN包,必须确认客户的SYN,同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN_RECV状态。
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,此包发送完毕,客户端和服务器进入ESTABLISHE)状态,完成三次握手。
38. 什么是套接字?
1.套接字,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程 。
2.应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字。
39.OSI的三层模型?
第一层:物理层,主要功能是利用物理传输介质为数据链路层提供物理连接,以便透明的传送比特流
第二层:数据链路层,在此层将数据分帧,并处理流控制
第三层:网络层,本层通过寻址来建立两个节点之间的连接,为源端的运输层送来的分组,选择合适的路由和交换节点,正确无误地按照地址传送给目的端的运输层。
40.简述一下系统调用和库函数,举例说明
库函数:
1.库函数调用是系统无关的,因此可移植性好。
2.库函数调用通常用于应用程序中对一般文件的访问。
3.由于库函数调用是基于C库的,因此也就不可能用于内核空间的驱动程序中对设备的操作。
4.读写文件通常是大量的数据,这时使用库函数就可以大大减少系统调用的次数。
5.依赖于系统调用函数,能提供较复杂的功能,如标准I/O库
7.用户无须定义,也不必在程序中作类型说明,只需在程序前包含有该函数原型的头文件即可在程序中直接调用,如使用 printf ,return;
系统调用:
1.系统调用是操作系统相关的,因此一般没有跨操作系统的可移植性。
2.系统调用通常用于底层文件访问。
3.系统调用发生在内核空间,有linux内核的对外接口,因此如果在用户空间的一般应用程序中使用系统调用来进行文件操作,会有用户空间到内核空间切换的开销。
4.系统调用是用户程序与内核之间的唯一接口,提供最小的接口。
5.是操作系统的一部分,用户应用程序访问并使用内核所提供的各种服务的途径即是系统调用。如 exit
41.VFS 是什么
1.虚拟文件系统(Virtual File System, 简称 VFS), 是 Linux 内核中的一个软件层,用于给用户空间的程序提供文件系统接口;同时,它也提供了内核中的一个 抽象功能,允许不同的文件系统共存。系统中所有的文件系统不但依赖 VFS 共存,而且也依靠 VFS 协同工作。
2.VFS 的作用就是采用标准的 Unix 系统调用读写位于不同物理介质上的不同文件系统,即 为 各类文件系统提供了一个统一的操作界面和应用编程接口。VFS 是一个可以让 open()、read()、 write()等系统调用不用关心底层的存储介质和文件系统类型就可以工作的粘合层。
42.进程结构
一个正在运行着的进程在内存空间中申请的代码区、初始化数据区、未初始化数据区、堆区、 栈区 5 个部分。
43. pthread_kill 函数和 pthread_cancle 函数的区别:
pthread_kill 函数的功能是向指定线程发送信号,信号为 0 时用于检查此线程 ID 的线程是否存活。 pthread_cancel 函数的功能是给线程发送取消信号,使线程从取消点退出。
44. pthread_exit()和 pthread_cancel()的区别
pthread_exit()是结束本线程,pthread_cancel()是结束其他线程
45. 简述互斥锁与读写锁的区别与联系。
区别:读写锁区分读者和写者,而互斥锁不区分 互斥锁同一时间只允许一个线程访问该对象,无论读写;读写锁同一时间内只允许一个写者, 但是允许多个读者同时读对象。
联系:读写锁在获取写锁的时候机制类似于互斥锁。
46. 条件变量中 pthread_cond_wait 实现的步骤
1.解锁
2.判断条件是否成立, 如果成立则上锁执行,不成立将进入阻塞状态
47. tcp 和 udp 的区别
1.TCP 需要连接,UDP 是无连接的,发送数据之前不需要建立连接 TCP 提供可靠的服务
2.通过 TCP 连接传送的数据,无差错,不丢失 TCP 逻辑通信信道是全双工的可靠信道,UDP 则是不可靠信道
48. 使用库函数也有系统调用的开销,为什么不直接使用系统调用呢?
这是因为读写文件通常是大量的数据,这时,使用库函数就可以大大减少系统调用的次数。
49. linux系统中的主要文件类型
普通文件、目录文件、字符设备或块设备文件、管道、套接字、链接文件、字符设备或块设备文件
50.哪种函数是系统调用函数,哪种是库函数,举出1-2个例子
库函数:ctime、malloc、free、time
系统调用函数:getpid、getppid、vfork、wait、waitpid
51. 能够写出open系统调用中的标志,至少5-6个(文件状态值)
O_RDONLY /* 为只读而打开 */
O_WRONLY /* 为只写而打开 */
O_RDWR /* 为读和写而打开 */
O_APPEND /* 总是在文件末尾写 */
O_NONBLOCK /* 非阻塞打开 */
O_DIRECTORY /* 如果文件不是一个目录,则失败 */
O_CREAT /*如果文件不存在则创建它 */
52. 什么是进程(概念),进程的资源分为哪两个部分
进程是Linux系统下资源管理、进行资源分配和调度的基本单元,每个进程都有自己独立的运行空间,是操作系统结构的基础,也是系统正在运行的一个程序,程序一旦运行就是进程;进程的运行空间是由进程的程序代码和程序
进程资源包括内核空间进程资源(PCB控制块)和用户空间进程资源。其中,内核空间进程资源需要父进程回收,而用户空间进程资源在进程退出后会自动释放。
53.进程的几种状态
1.运行态Running
2.可唤醒阻塞态Interruptible
3.不可唤醒阻塞态Uninterruptible
4.僵死状态Zombie
5.停滞状态Stopped
54. 进程的调度策略:policy:
1.SCHED_FIFO:不同的进程根据静态优先级进行排队,然后在同一优先级的队列中,谁先准备好运行就先调度谁,并且正在运行的进程不会被终止直到以下情况发生:1.被有更高优先级的进程所强占CPU;2.自己因为资源请求而阻塞;3.自己主动放弃CPU(调用sched_yield);
2.SCHED_RR:它给每个进程分配一个时间片,时间片到了,正在执行的进程就放弃执行。
3.SCHED_FIFO和SCHED_RR是实时进程调度策略,只针对优先级相同并且都是就绪状态的的进程。
4.SCHED_OTHER是普通进程,常规分时调度策略。
55.exec函数族的作用
作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件。这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件。
与一般情况不同,exec函数族的函数执行成功后不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样,颇有些神似"三十六计"中的"金蝉脱壳"。看上去还是旧的躯壳,却已经注入了新的灵魂。
只有调用失败了,它们才会返回一个-1,从原程序的调用点接着往下执行。
56.system函数的基本功能
功能:可以让一个程序在另一个程序的内部运行,也就是说,我们创建了一个新的进程,这个工作可以通过库函数system来实现。
57.进程间通信的目的:
复杂的编程环境通常要使用多个相关的进程来执行有关操作。进程之间必须进行通信来共享资源和信息。进程间通信IPC(interprocess Communication)提供了一种不同进程间可以互相访问数据的方式。
1、数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间。
2、共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。
3、通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
4、资源共享:多个进程之间共享同样的资源。为了作到这一点,需要内核提供锁和同步机制。
5、进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有异常,并能够及时知道它的状态改变。
58.进程间通信的常见方式:
匿名管道、有名管道、信号
59.可靠信号和不可靠信号在注册时的差异性:
1.当一个实时信号发送给一个进程时,不管该信号是否已经在进程中注册,都会被再注册一次,因此,信号不会丢失,因此,实时信号又叫做"可靠信号"。这意味着同一个实时信号可以在同一个进程的未决信号信息链中占有多个sigqueue结构(进程每收到一个实时信号,都会为它分配一个结构来登记该信号信息,并把该结构添加在未决信号链尾,即所有诞生的实时信号都会在目标进程中注册);
2.当一个非实时信号发送给一个进程时,如果该信号已经在进程中注册,则该信号将被丢弃,造成信号丢失。因此,非实时信号又叫做"不可靠信号"。这意味着同一个非实时信号在进程的未决信号信息链中,至多占有一个sigqueue结构(一个非实时信号诞生后,(1)、如果发现相同的信号已经在目标结构中注册,则不再注册,对于进程来说,相当于不知道本次信号发生,信号丢失;(2)、如果进程的未决信号中没有相同信号,则在进程中注册自己)。
60.线程概念和特点
1.线程是在一个程序内部可以被操作系统调度并发运行的任务。
2.线程有自己的运行线索,可完成特定任务。
3.线程自己基本上不拥有系统资源,只拥有少量在运行中必不可少的资源。
4.与同属一个进程的其他线程共享进程所拥有的全部资源。
5.可通过相互协同来完成进程所要完成的任务。
61.线程的创建和终止
int pthread_create();
参数说明:
Thread:要创建的线程id指针
Attr:创建线程时的线程属性
(*start_routine)(void*):返回值是void*类型的指针函数
Arg:start_routine的参数
返回值:成功返回0,失败返回错误编号
62.读写锁的分类
读锁:如果当前线程申请读锁,其他线程可以申请读锁,但是不能申请写锁;
写锁:如果某线程申请写锁,其他线程不能申请写锁,也不能申请读锁。