IO进程常见问题小结

1.标准IO和文件IO的区别

标准I/O

文件IO

概念

C库中定义的一组用于输入输出的函数

系统中定义的一组用于输入输出的函数

特点

1)有缓冲机制,减少系统调用

2)围绕文件流进行操作

3)默认打开三个文件流,stdin、stdout、stderr

4)只能对普通文件进行操作

1)无缓冲机制,每次都要系统调用

2)围绕文件描述符进行操作

3)默认打开3个文件描述符,0,1,2

4)可以对任意类型文件操作,目录除外

函数

打开文件:fopen freopen

关闭文件:fclose

文件读写:fgetc fputc fgets fputs fread fwrite

文件定位操作:fseek ftell rewind

打开文件:open

关闭文件:close

文件读写:read write

文件定位操作:lseek

diff 文件一 文件二:对比两个文件有无不同

2.静态库和动态库的区别

静态库和动态库,本质区别是代码被载入时刻不同。

1) 静态库在程序编译时会被连接到目标代码中。

优点:程序运行时将不再需要该静态库;运行时无需加载库,运行速度更快。

缺点:静态库中的代码复制到了程序中,因此体积较大;

静态库升级后,程序需要重新编译链接

2) 动态库是在程序运行时才被载入代码中。

优点:程序在执行时加载动态库,代码体积小;程序升级更简单;

不同应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

缺点:运行时还需要动态库的存在,移植性较差

3.怎么创建进程

pid_t pid=fork();

4.什么是守护进程

守护进程是后台进程;生命周期比较长,从系统启动时开启,系统关闭时结束;它是脱离控制终端且周期执行的进程。

步骤:

1) 创建子进程,父进程退出

让子进程变成孤儿进程,成为后台进程;fork()

2) 在子进程中创建新会话

让子进程成为会话组组长,为了让子进程完全脱离终端;setsid()

3) 改变进程运行路径为根目录

原因进程运行的路径不能被删除或卸载;chdir("/")

4) 重设文件权限掩码

目的:增大进程创建文件时权限,提高灵活性;umask(0)

5) 关闭文件描述符

将不需要的文件关闭;close()

5.什么是僵尸进程?什么是孤儿进程?

1)子进程几乎拷贝了父进程的全部内容。包括代码、数据、系统数据段中的pc值、栈中的数据、父进程中打开的文件等;但它们的PID、PPID是不同的。

2)父子进程有独立的地址空间,互不影响;当在相应的进程中改变全局变量、静态变量,都互不影响。

3)若父进程先结束,子进程成为孤儿进程,被init进程收养,子进程变成后台进程。

4)若子进程先结束,父进程如果没有及时回收,子进程变成僵尸进程(要避免僵尸进程产生)。进程已经终止运行,但还占用系统资源

6.时间片了解么?

在宏观上:我们可以同时打开多个应用程序,每个程du序并行不悖,同时运行。
但是在微观上:由于只有一个CPU,一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间片,每个程序轮流执行。

时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间,使各个程序从表面上看是同时进行的。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。而不会造成CPU资源浪费。在宏观上:我们可以同时打开多个应用程序,每个程序并行不悖,同时运行。但在微观上:由于只有一个CPU,一次只能处理程序要求的一部分,如何处理公平,一种方法就是引入时间片,每个程序轮流执行。

7.进程和线程区别?

共性:都为操作系统提供了并发执行能力

不同点:

调度和资源:线程是系统调度的最小单位,进程是资源分配的最小单位

地址空间方面:同一个进程创建的多个线程共享进程的资源;进程的地址空间相互独立

通信方面:线程通信相对简单,只需要通过全局变量可以实现,但是需要考虑临界资源访问的问题;进程通信比较复杂,需要借助进程间的通信机制(借助3g-4g内核空间)

安全性方面:线程安全性差一些,当进程结束时会导致所有线程退出;进程相对安全

临界资源:一次仅允许一个线程使用共享资源

8.线程的同步怎么实现

通过信号量、互斥锁、条件变量

信号量:通过信号量实现同步操作;由信号量来决定线程是继续运行还是阻塞等待

信号量代表某一类资源,其值表示系统中该资源的数量,信号量值>0,表示有资源可以用,可以申请到资源,继续执行程序,信号量值=0,表示没有资源可以用,无法申请到资源,阻塞。

信号量是一个受保护的变量,只能通过三种操作来访问:初始化sem_init、P操作(申请资源)sem_wait、V操作(释放资源)sem_post

信号量的值为非负整数

1.初始化信号量 int sem_init(sem_t *sem, int pshared, unsigned int value)

2. 申请资源 int sem_wait(sem_t *sem)

3. 释放资源 int sem_post(sem_t *sem)

9.线程的互斥怎么实现

互斥:多个线程在访问临界资源时,同一时间只能一个线程访问

互斥锁:通过互斥锁可以实现互斥机制,主要用来保护临界资源,每个临界资源都由一个互斥锁来保护,线程必须先获得互斥锁才能访问临界资源,访问完资源后释放该锁。如果无法获得锁,线程会阻塞直到获得锁为止。

1. 初始化锁,pthread_mutex_init

2. 申请互斥锁 pthread_mutex_lock

3. 释放互斥锁 pthread_mutex_unlock

4. 销毁互斥锁 pthread_mutex_destroy

10.进程间通信方式有哪些?哪种效率最高

线程通信:全局变量

1. 早期通信:无名管道、有名管道、信号

2. system V IPC:共享内存、消息队列、信号灯集

3. BSD:socket通信

共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝

11.通信方式的优缺点对比

【1】无名管道

1. 只能用于具有亲缘关系的进程间通信

2. 半双工通信方式,有固定的读端和写端

半双工:可以双向通信,但是同一时刻只能单向传输信息。

全双工:可以双向同时通信。

单工:单向传送信息。

3. 无名管道可以看作特殊的文件,对它的读写可以使用文件IO操作read、write

4. 无名管道基于文件描述符进行操作,当一个管道建立,它会创建两个文件描述符

fd[0]固定的读管道,fd[1]固定的写管道

【2】有名管道

1. 特点:***

1. 有名管道可以使互不相干进程进行通信

2. 有名管道可以通过路径名指出,在文件系统中可见,但数据内容存放在内存中。

3. 通过文件IO进行操作,

4. 遵循先进先出原则

5. 不支持lseek()操作。

【3】共享内存

1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝

2)为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间

3)进程就可以直接读写这一内存区而不需要进行数据的拷贝,从而大大提高的效率。

4)由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等

【4】消息队列

消息队列是IPC对象的一种

消息队列由消息队列ID来唯一标识

消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等。

消息队列可以按照类型来发送(添加)/接收(读取)消息

12.有名管道和无名管道的区别?

**【3】有名管道无名管道对比

无名管道

有名管道

使用场景

亲缘关系

互不相干

特点

半双工通信

具有固定的读端fd[0]和写端fd[1]

看作特殊文件,文件IO操作

半双工通信

先进先出,不支持lseek操作

通过文件IO进行操作,在系统中可见,但数据存放在内存中

函数

pipe()

可直接进行读写操作

mkfifo()

要先open,在进行读写操作

读写特性

当管道中无数据,读阻塞

当管道中写满数据,写阻塞

读端关闭,继续写会导致管道破裂

只写方式写阻塞,直到另一个进程将读打开

只读方式读阻塞,直到另一个进程将写打开

可读可写,若管道中无数据,读阻塞

13.共享内存的实现方式

1.创建key值 ftok

2. 创建或打开共享内存 shmget

3. 映射共享内存到用户空间 shmat

4. 撤销映射shmdt

5. 删除共享内存shmctl

命令

ipcs -m :查看系统中共享内存

ipcrm -m shmid:删除shmid号的共享内存

14.消息队列的实现方式

1. 创建key值ftok

2. 创建或者打开消息队列 msgget

3. 添加消息:按照类型将消息添加到已经代开的消息队列末尾msgsnd

4. 读取消息:可以按照类型读取消息msgrcv

5. 删除消息队列msgctl

命令

ipcs -q:查看消息队列

ipcrm -q msgid:删除编号为msgid的消息队列

15.fork和vfork区别

1.fork(): 子进程拷贝父进程的数据段,代码段

vfork(): 子进程与父进程共享数据段

2.fork(): 父子进程执行次序不确定

vfork(): 保证子进程先运行,在调用exec()或exit()之前,与父进程数据共享,在exec()或exit()调用之后,父进程才能运行

3. 在使用vfork函数在调用exec()或exit()之前,子进程依赖于父进程的进一步动作,将会导致死锁。

16.线程的死锁,怎么避免?

死锁产生的四个必要条件

1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用

2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。

3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。

4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。

注意:当上述四个条件都成立的时候,便形成死锁。当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值