I/O进程3

  • day3
    • 五、进程
      • 7.函数接口
        • 7.1创建子进程
          • pid_t fork(void);
          • 功能:创建子进程
          • 返回值:成功:在父进程中:返回子进程的进程号 >0  在子进程中:返回值为0;  失败:-1并设置errno
          • 特点
            • 1.子进程几乎拷贝了父进程的所有内容,包括代码、数据,缓冲区,系统数据段中的值,栈中的数据,父进程打开的文件,但是PID,PPID不同
            • 2.fork之前的代码会被复制但是不会被重新执行,fork之后的代码会被复制,并且父子进程分别执行一遍。
            • 3.父子进程的空间相互独立,互不影响,当在相应的进程中改变全局变量,静态变量,都互不影响
            • 4.fork之前打开的文件,fork之后拿到的是同一个文件描述符,操作的是同一个文件指针
            • 5.若父进程先结束,子进程成为孤儿进程,被init进程所收养,会变成后台进程。
            • 6.若子进程先结束,父进程不结束,父进程没有及时回收,子进程就会变成僵尸进程(避免僵尸进程的产生)
      • 8.回收进程
        • pid_t wait(int *status);
        • 功能:回收子进程资源(阻塞)
        • 参数:status:子进程退出状态,不接受子进程状态设为NULL
        • 返回值:成功:回收的子进程的进程号       失败:-1                                                                          
        • pid_t waitpid(pid_t pid, int *status, int options);
        • 功能:回收子进程资源
        • 参数:
        • pid:>0 指定子进程进程号        =-1 任意子进程        =0 等待其组ID等于调用进程的组ID的任一子进程          <-1 等待其组ID等于pid的绝对值的任一子进程    
        • status:子进程退出状态    
        • options:0:阻塞          WNOHANG:非阻塞
        • 返回值:正常:结束的子进程的进程号      当使用选项WNOHANG且没有子进程结束时:0       出错:-1
      • 9.结束进程
        • void exit(int status);
        • 功能:结束进程,刷新缓存
        • 参数:退出的状态 不返回。
      • 10.获取进程号
        • pid_t getpid(void);
        • 功能:获取当前进程的进程号
        • pid_t getppid(void);
        • 功能:获取当前进程的父进程号
    • 六、进程间通信
      • 1.为什么要进行进程间通信
        • 数据传输、资源共享、事件通知、进程控制
      • 2.进程间通信方式(7)
        • (1).早期进程间通信 无名管道(pipe)、有名管道(fifo)、信号(sem)
        • (2).system V IPC通信 共享内存(share memory)、消息队列(message queue)、信号灯集(semaphore)
        • (3).BSD: 套接字(socket)
      • 3.无名管道
        • 3.1原理图
          • 通信原理:一个进程的输出可以当作另一进程的输入
        • 3.2特点
          • (1).只能用于具有亲缘关系的进程间通信
          • (2).半双工通信模式,具有固定的读端和写端 {单工:只能单方向通信, 广播 半双工:可以双向通信,但是同一时间不可以 对讲机 全双工:可以双向同时通信 打电话}
          • (3).无名管道可以被看做一个特殊的文件,对于他的读写可以使用文件IO函数 (注意:不是文件,他只是存在于内核空间的一部分,无实际文件)
          • (4).管道基于文件描述符进行通信。当一个管道建立的时候,它会自动创建两个文件描述符,一个用于读fd[0],一个用于写fd[1]。
        • 3.3函数
          • int pipe(int fd[2])
          • 功能:创建无名管道
          • 参数:文件描述符 fd[0]:读端 fd[1]:写端
          • 返回值:成功 0       失败 -1
      • 4.有名管道(FIFO)
        • 4.1特点
          • (1).可以使互不相干的两个进程通信
          • (2).有名管道可以通过路径名来指出,并在文件系统中可见,但是内容存储在内存中
          • (3).进程通过文件IO操作有名管道
          • (4).有名管道遵循先进先出的原则,不支持lseek()操作
          • (5).半双工通信
        • 4.2函数
          • int mkfifo(const char *filename,mode_t mode);
          • 功能:创建有名管道
          • 参数:filename:有名管道文件名        mode:权限
          • 返回值:成功:0        失败:-1,并设置errno号
    • 七、信号
      • 1.例子
        • kill -l:查看系统中信号
        • kill -num pid:给pid进程发送pid信号
      • 2.概念
        • (1).信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式。 (2).信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。 (3).如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。
      • 3.信号响应方式
        • (1.)忽略信号:对信号不做任何处理,但是有两个信号不能做忽略处理:SIGKILL和SIGSTOP
        • (2).捕捉信号:定义信号处理函数,当信号发生的时候,执行相应的处理函数,但是有两个信号不能做捕捉处理:SIGKILL和SIGSTOP
        • (3).执行缺省操作:linux对每种信号都规定了默认信号。
      • 4.信号的种类
        • 2)SIGINT:结束进程,对应快捷方式ctrl+c
        • 3)SIGQUIT:退出信号,对应快捷方式ctrl+\
        • 9)SIGKILL:结束进程,不能被忽略不能被捕捉
        • 14)SIGALRM:闹钟信号,alarm函数设置定时,当到设定的时间时,内核会向进程发送此信号结束进程。
        • 15)SIGTERM:结束终端进程,kill 使用时不加数字默认是此信号
        • 17)SIGCHLD:子进程状态改变时给父进程发的信号
        • 19)SIGSTOP:暂停进程,不能被忽略不能被捕捉
        • 20)SIGTSTP:暂停信号,对应快捷方式ctrl+z
        • 信号的种类
        • 在Linux中,信号被分为不可靠信号和可靠信号,一共64种,可以通过kill -l命令来查看
        • ●不可靠信号:也称为非实时信号,不支持排队,信号可能会丢失,比如发送多次相同的信号,进程只能收到一次,信号值取值区间为1~31
        • ●可靠信号:也称为实时信号,支持排队,信号不会丢失,发多少次,就可以收到多少次,信号值取值区间为32~64 信号产生的方式有如下几种:
        • ● 对于前台进程,用户可以输入特殊终端字符来发送,比如输入Ctrl+C
        • ● 系统异常,比如浮点异常和非法内存段访问
        • ● 系统状态变化,比如alarm定时器到期时将引起SIGALRM信号
        • ● 在终端运行kill命令或在程序中调用kill函数
      • 5.函数接口
        • 5.1发送信号
          • int kill(pid_t pid, int sig);
          • 功能:信号发送
          • 参数:pid:指定进程           sig:要发送的信号
          • 返回值:成功 0              失败 -1     
          •                                              
          •  int raise(int sig);
          • 功能:进程向自己发送信号
          • 参数:sig:信号
          • 返回值:成功 0              
          • 失败 -1                                                 
          •   int pause(void);
          • 功能:用于将调用进程挂起,直到收到信号为止。 
        • 5.2定时器
          • unsigned int alarm(unsigned int seconds)
          • 功能:在进程中设置一个定时器
          • 参数:seconds:定时时间,单位为秒
          • 返回值:如果调用此alarm()前,进程中已经设置了闹钟时间,则 返回上一个闹钟时间的剩余时间,否则返回0。
          • 注意:一个进程只能有一个闹钟时间。如果在调用alarm时 已设置过闹钟时间,则之前的闹钟时间被新值所代替
        • 5.3信号处理
          • #include <signal.h>
          • typedef void (*sighandler_t)(int);
          • sighandler_t signal(int signum, sighandler_t handler);
          • 功能:信号处理函数
          • 参数:
          • signum:要处理的信号          
          • handler:信号处理方式              
          • SIG_IGN:忽略信号              
          • SIG_DFL:执行默认操作              
          • handler:捕捉信号 void handler(int sig){} //函数名可以自定义
          • 返回值:成功:设置之前的信号处理方式              失败:-1
    • 八、共享内存
      • 1.特点
        • (1).共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,不需要进行任何数据的拷贝
        • (2).为了在多个进程间进行数据的交互,内核专门留了一块内存区,可以由需要访问的进程将其映射到自己的地址空间
        • (3).由于多个进程共享一段内存,因此也需要依靠某种同步机制,如互斥锁和信号量等
      • 2.编程步骤
        • (1).创建或者打开共享内存shmget
        • (2).映射共享内存到自己的用户空间shmat
        • (3).使用共享内存
        • (4).撤销映射
        • (5).删除共享内存
      • 3.函数接口
        • int shmget(key_t key, size_t size, int shmflg);
        • 功能:创建或打开共享内存
        • 参数:     key 键值     size 共享内存的大小     shmflg IPC_CREAT|IPC_EXCL(判错)|0666
        • 返回值:成功 shmid              出错 -1
        • void *shmat(int shmid,const void *shmaddr,int shmflg);
        • 功能:映射共享内存,即把指定的共享内存映射到进程的地址空间用于访问
        • 参数:    
        • shmid 共享内存的id号    
        • shmaddr 一般为NULL,表示由系统自动完成映射,如果不为NULL,那么由用户指定    
        • shmflg:SHM_RDONLY就是对该共享内存只进行读操作  ,0 可读可写
        • 返回值:成功:完成映射后的地址,       失败:-1的地址
        • 用法:if((p = (char *)shmat(shmid,NULL,0)) == (char *)-1)                 
        •  int shmdt(const void *shmaddr);
        • 功能:取消映射
        • 参数:要取消的地址
        • 返回值:成功0       失败的-1                                                                                             
        • int shmctl(int shmid,int cmd,struct shmid_ds *buf);
        • 功能:(删除共享内存),对共享内存进行各种操作
        • 参数:    
        • shmid 共享内存的id号    
        • cmd IPC_STAT 获得shmid属性信息,存放在第三参数            
        • IPC_SET 设置shmid属性信息,要设置的属性放在第三参数            
        • IPC_RMID:删除共享内存,此时第三个参数为NULL即可
        • 返回:成功0      失败-1
        • 用法:shmctl(shmid,IPC_RMID,NULL);
      • 4.命令
        • ipcs -m:查看系统中共享内存
        • ipcrm -m shmid :删除共享内存