没有合适的资源?快使用搜索试试~ 我知道了~
c++面试题网络编程篇
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 55 浏览量
2022-06-18
11:11:13
上传
评论
收藏 1.01MB DOCX 举报
温馨提示
试读
23页
c++面试题网络编程篇
资源推荐
资源详情
资源评论
c++⾯试题⽹络编程篇
dup 和 dup2
dup2 通常⽤于重定向,如下⾯的代码就是将标准输出重定向到指定的 fd 中。
int fd = open("output.txt", O_RDWR|O_CREAT, 0666);
int replaced = dup2(fd, STDOUT_FILENO);
lseek 函数
off_t lseek(int fd,off_t offset, int whence);
如果
如果
如果
是
是
是
,则将⽂件的偏移量设置为距⽂件开始处 offset 个字节。
whence
whence
whence
SEEK_SET
SEEK_CUR
SEEK_END
,则将⽂件的偏移量设置为其当前值加 offset 个字节,offset 可正可负。
,则将⽂件的偏移量设置为⽂件长度加 offset,offset 可正可负。
sync fsync 和 fdatasync 函数
sync 只是将所有修改过的块缓冲区排⼊写队列,然后就返回(⾮阻塞);
fsync 只对⽂件描述符 fd 指定的⼀个⽂件起作⽤,并等待写磁盘操作完成 (阻塞);
fdatasync 类似于 sync,但是只刷数据,不刷⽂件属性。
fcntl 函数的作⽤
fcntl 函数有 5 种功能
1.复制⼀个已有的描述符(cmd = F_DUPFD 或者 F_DUPFD_CLOEXEC)。
2.获取/设置⽂件描述符标志(cmd = F_GETFD 或 F_SETFD)
3.获取/设置⽂件状态标志(cmd = F_GETFL 或 F_SETFL)
4.获取/设置异步 IO 所有权(cmd = GETOWN 或者 F_SETOWN)
5.获取/设置记录锁(cmd = F_GETLK,F_SETLK,F_SETLKW).
exit 和_exit 的区别
exit()函数与_exit()函数最⼤的区别就在于 exit()函数在调⽤exit 系统调⽤之前要检查⽂件的打开情况,把⽂件缓冲区中的内容写回⽂件,即
所谓的"清理 I/O 缓冲"。
setjmp 和 longjmp 的⽤法
参考例⼦:
}
setjmp ret = 0
enter into first
setjmp ret = 5
return to main
第⼀次通过 set jmp 设置跳转上下⽂参数,设置参数是 s etlong 返回的是 0。
所以第⼀次进⼊了 if 语句中执⾏了 first 函数,在 first 函数中通过 longjmp 返回,通过 longjmp 返回的到 setjmp 时,setjmp 的返回值不为 0。
规则是 l ongjmp 的第⼆个参数是 0,则 setjmp 返回 1,如果 longjmp 第⼆个参数是其他值,则返回该值。本例中,longjmp 返回 5,所以
setjmp 返回 5.
记录锁的作⽤
记录锁不仅仅可以⽤来同步不同进程对同⼀⽂件的操作,还可以通过对同⼀⽂件加记录锁,来同步不同进程对某⼀共享资源的访问,如共享
内存,I/O 设备。
守护进程编程规范
1.⾸先要做的是调⽤umask,重设⽂件权限掩码。
⽂件权限掩码是指屏蔽掉⽂件权限中的对应位。⽐如,有个⽂件权限掩码是 050,它就屏蔽了⽂件组拥有者的可读与可执⾏权限。
由于使⽤fork 函数新建的⼦进程继承了⽗进程的⽂件权限掩码,这就给该⼦进程使⽤⽂件带来了诸多的⿇烦。
因此,把⽂件权限掩码设置为 0,可以⼤⼤增强该守护进程的灵活性。
设置⽂件权限掩码的函数是 umask。在这⾥,通常的使⽤⽅法为 umask(0)。
2.调⽤fork,然后将⽗进程退出(exit)。
这是编写守护进程的第⼀步。由于守护进程是脱离控制终端的,因此,完成第⼀步后就会在 Shell 终端⾥造成⼀程序已经运⾏完毕的假
象。
之后的所有⼯作都在⼦进程中完成,⽽⽤户在 Shell 终端⾥则可以执⾏其他命令,从⽽在形式上做到了与控制终端的脱离。
在 Linux 中⽗进程先于⼦进程退出会造成⼦进程成为孤⼉进程,⽽每当系统发现⼀个孤⼉进程是,就会⾃动由 1 号进程(init)收养它。
这样,原先的⼦进程就会变成 init 进程的⼦进程。
3.调⽤setsid 以创建⼀个新会话。
由于创建守护进程的第⼀步调⽤了 fork 函数来创建⼦进程,再将⽗进程退出。由于在调⽤了 fork 函数时,⼦进程全盘拷贝了⽗进程的会
话期、进程组、控制终端等。
虽然⽗进程退出了,但会话期、进程组、控制终端等并没有改变,因此,还还不是真正意义上的独⽴开来,⽽setsid 函数能够使进程完
全独⽴出来,从⽽摆脱其他进程的控制。
4.当前⼯作⽬录更改为根⽬录。从⽗进程继承过来的当前⼯作⽬录可能在⼀个装配⽂件系统中。因为守护进程可能会在系统再引导之前
就⼀直存在,所以如果守护进程的当前⼯作⽬录。在⼀个装配⽂件系统中,那么该⽂件系统就不可拆卸。这与装配⽂件系统的原意不
符。
5.闭不再需要的⽂件描述符。⽤fork 函数新建的⼦进程会从⽗进程那⾥继承⼀些已经打开了的⽂件。这些被打开的⽂件可能永远不会被
守护进程读写,但它们⼀样消耗系统资源,⽽且可能导致所在的⽂件系统⽆法卸下。
6.些守护进程打开/dev/null 使其具有⽂件描述符 0、1 和 2
因为守护进程并不与终端设备相关联,所以不能再终端设备上显⽰其输出,也⽆处从交互式⽤户那⾥接收输⼊。
常见信号及其触发⽅法
SIGINT ctrl +c 终⽌信号
SIGQUIT ctrl+\ ⽣成 core⽂件
SIGTSTP ctrl+z
信号的忽略和信号的阻塞的区别
处理信号两个动作,⼀个是接受信号,⼀个是处理信号。
如果可以接受信号,但是暂时不处理,就称为信号阻塞。
所以选择阻塞某个信号,但是在这个期间收到了该信号,就称这个信号是未决的(pending)。
如果可以接受信号,处理信号的动作是忽略该信号,不做任何动作,就成为忽略信号。
举个例⼦,
电视台有⼀个举报电话 10101,然后可以接受投诉。但是某段时间由于投诉太多,只接受某⼏个⽤户的投诉,其他⽤户的投诉暂时不处
理。这个过程就可以类⽐于信号阻塞。
然后不忙的时候,所有⼈投诉都处理,结果有个⼈打来了骚扰电话,就直接挂掉电话,这个过程可以类⽐于信号忽略。
可靠信号和不可靠信号
不可靠信号
Linux 信号机制基本上是从 Unix 系统中继承过来的。早期 Unix 系统中的信号机制⽐较简单和原始,因此,把那些建⽴在早期机制上的信号叫
做"不可靠信号",信号值⼩于 SIGRTMIN 的信号都是不可靠信号(Red hat 7.2 中,SIGRTMIN=32,SIGRTMAX=63)。
它的主要问题是:
进程每次处理信号后,就将对信号的响应设置为默认动作。在某些情况下,将导致对信号的错误处理;因此,⽤户如果不希望这样的操
作,那么就要在信号处理函数结尾再⼀次调⽤signal(),重新安装该信号。
信号可能丢失,后⾯将对此详细阐述。 如果在进程对某个信号进⾏处理时,这个信号发⽣多次,对后到来的这类信号不排队,那么仅
传送该信号⼀次,即发⽣了信号丢失。
因此,早期 unix 下的不可靠信号主要指的是进程可能对信号做出错误的反应以及信号可能丢失。
Linux⽀持不可靠信号,但是对不可靠信号机制做了改进:在调⽤完信号处理函数后,不必重新调⽤该信号的安装函数(信号安装函数
是在可靠机制上的实现)。因此,Linux 下的不可靠信号问题主要指的是信号可能丢失。(触发多次,只处理⼀次)
**可靠信号**是指信号值位于 SIGRTMIN 和 SIGRTMAX 之间的信号,可靠信号**⽀持排队**,克服了**信号可能丢失的问题**。
sigpromask 的作⽤
sigprocmask 的作⽤是阻塞信号
int sigprocmask(int how,const sigset_t * set, sigset_t *oset);
参数 how 代表:
阻塞 (SIG_BLOCK): 将现有的信号阻塞集 和 set 信号集的并集 设置为阻塞,
解除阻塞(SIG_UNBLOCK):将现有信号阻塞集中的信号和 set 信号集的交集,解除阻塞。
重新设置(SIG_SETMASK):设置进程新的信号阻塞集。
sigpending 的作⽤
取出当前进程收到的属于阻塞信号集中的信号,也就是所谓的未决信号。
int sigpending(sigset_t , *set)
sigact ion 的作⽤
注册信号处理函数
int sigaction(int signo,const struct sigaction *act,struct sigaction *oact);
标准 IO 的缓冲
全缓冲:对于驻留在磁盘上的⽂件通常是全缓冲的。
⾏缓冲:遇到换⾏符"\n" 或者 指向终端设备的流是⾏缓冲的。
⽆缓冲:标准错误是不带缓冲的。
线程同步 -互斥锁
{
count++;
printf("fun1 count = %d\n",count);
}
}
{
pthread_mutex_lock(&mutex);
count++;
printf("fun2 count = %d\n",count);
pthread_mutex_unlock(&mutex);
}
}
int main()
{
int ret1,ret2;
printf("in main count = %d\n",count);
进程间通讯⽅式的⽐较和优缺点
管道:速度慢,容量有限,仅仅有⽗⼦进程能通讯(有半双⼯的 pipe 以及全双⼯的 socketpair,使⽤环境⼏乎⼀致)
FIFO(命名管道):不论什么进程间都能通讯,但速度慢,⽤于⼀些效率不⾼的场合,⽐如发⼀些命令给别的进程。
消息队列:容量受到系统限制,且要注意第⼀次读的时候,要考虑上⼀次没有读完数据的问题,并且长度类型⼀定是要 long 类型,否
则 msgrcv 会阻塞⽆法成功接收。
信号量:不能传递复杂消息,仅仅能⽤来同步。
共享内存区:速度快,但是没有同步机制,通常⽤于⼀些进程间交换⼤数据的场合,⽐如视频、⽂件复制之类。
socket 本地域通信:和不同机器之间 socket 通信⽅式⼤致相同,功能强⼤,⽬前在很多开源程序上很常见,⽐如 wpa_supplicant 和
wpa_cli 通信机制,⽬前如果对销量要求较⾼,相对复杂,数据量不是⼗分⼤的,推荐采⽤socket IPC。
剩余22页未读,继续阅读
资源评论
码农.one
- 粉丝: 7
- 资源: 345
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功