进程与进程管理:
清屏:system("clear"); //#include <signal.h>
系统调用:
write(文件描述符,字符串,字符串大小)。read(文件描述符,字符串,字符串大小),读取文件中前‘字符串大小‘的内容,并保存到字符串中(而且只要open不更改打开模式,默认情况会在文件内容为空时,阻塞进程);成功则返回读到的字符串大小(0-‘字符串大小‘),否则返回-1。
open(文件名,打开模式),返回文件描述符。close(文件描述符),关闭用open打开的文件,所以参数文件描述符为open返回过的。
进程环境与进程属性:
什么是进程:简单的说,进程就是程序的一次执行过程。
进程的状态:进程三态:运行态、就绪态、封锁态——状态可在一定的条件下变化。(其中处于等待的进程分为:可中断进程可以被信号中断其等待;不可中断进程在任何情况下都不可被中断,一直等待条件的满足)。僵死进程:子进程先于父进程退出;从子进程终止到父进程调用wait()之前的时间段内,子进程被称为僵死进程zombie(因为只有父进程能回收,而父进程没有回收其资源)/ 孤儿进程:父进程先于子进程退出,子进程被称为孤儿进程(被进程0/init进程?回收)
进程的执行模式与类型:执行模式分为用户模式—中断/系统调用—>内核模式。进程类型分为用户进程—中断/系统调用—>系统进程。
进程的属性:查看进程的属性:非实时ps aux/auxf、实时top。每一列的含义(有空再看)。会话(进程组的集合):一个会话可以没有控制终端,也可以与一个终端建立连接,建立连接的会话首进程称为控制进程;一个会话可以有几个进程组,可分为一个前台进程组(当会话带有一个终端)和多个后台进程组。其特点:无论何时在终端输入中断信号(ctrl+c)或终端的退出键,就会有中断信号或退出信号发送给前台进程组的所有进程。
获取/设置进程组号(PGID):getpgid(pid) / int setpgid(pid, pgid)、获取进程的会话号:getsid(sid) ;创建会话:pid_t setsid()返回进程号,该进程作为会话首进程。控制终端函数:pid_t tcgetpgrp(int filedes)、pid_t tcsetpgrp(int filedes, pid_t pgrpid)、pid_t tcgetsid(int filedes)(有空再看)。
进程用户属性:
真实用户号(RUID)、有效用户号(EUID)、进程用户号(GID)、有效进程用户组号(EGID):有空再看。
进程的管理:
创建进程:pid_t fork();执行成功后,如果父进程抢到了执行权,则返回子进程的PID,如果子进程抢到了执行权,则返回0,否则执行失败,返回-1;这个函数是系统调用,对父进程复制,所以子进程几乎与父进程一样,代码相同,对文件采用共享方式,但是数据和文件描述符采用独占方式。/ vfork()函数与父进程共享数据空间,这种方式执行效率较高,执行顺序是子先父后。
退出进程:
on_exit(test_exit, (void *)str);该函数有两个参数,第一个是:进程结束前,调用的test_exit函数,如void test_exit(int status, void *arg){...},test_exit函数的第一个参数必须是进程结束时exit(status)的status;第二个(应该不止示例中的参数)的参数就是:传递给test_exit函数的arg,的str。
进程的正常结束void exit(int status):进程的缓冲区数据自动写回、关闭未关闭的文件。#include <stdlib.h>
void _exit(int status):进程的缓冲区数据不会自动写回、不会自动关闭文件。#include <unistd.h>
等待进程(等待子进程中断或结束):pid_t wait(int *status);停止当前进程的执行,直到有信号到来或者其子进程结束。如果子进程已结束,执行wait时会立即返回子进程id和结束状态(保存在参数status中)。status也可以不写,还有一些测试宏(#include <stdlib.h>)。有错误(没有子进程)则返回-1。一发现终止的子进程,就根据其pid释放子进程占用的task_struct和系统空间堆栈(就是资源),然后把该子进程的CPU使用时间加到其父进程上。
替换当前进程:#include <unistd.h>
int execl(const char *path, const char *arg, ...)、int execlp(const *file, const char *arg, ...)、int execv(const char *path, const char *argv[])、int execvp(const char *file, const char *argv[])、execve(const char *filename, const char *argv[], const char *envp[])
进程的调度算法(暂时不管)。
进程间通信:
一些基本概念:
进程同步:一个功能未完成,就不返回(一件事做完,才做下一件)
进程异步:各做各的,每当有一件事做完后就通知调用者。
IPC:进程间通信。每个IPC机制都有唯一ID,通过KEY创建。
三种继承自System V的IPC机制:信号量、消息队列、共享内存。
同主机,进程间异步机制:信号(signal)
信号安装:
signal(信号,函数)——>函数可以不带参数,也可以带一个参数(参数为信号,信号就是一堆int值)。
sigaction(信号,信号结构体,信号结构体)。——>第二个参数安装现在的信号(如果为空指针,则保持原来的信号不变),第三个为之前的信号结构体。
信号结构体:1、.sa_handler信号处理函数。2、.sa_mask信号处理函数执行过程中,阻塞掉的其他信号。3、.sa_flags用于更改指定信号的行为。
同主机,进程间同步机制:信号量(semaphore)
同主机,进程间数据交互机制:无名管道(PIPE)、有名管道(FIFO)、消息队列、内存映射、共享内存,管道和消息队列都自带同步机制,内存映射、共享内存则无同步。
管道的创建都不用头文件。
无名管道PIPE:每个管道只有一个内存页面做环形缓冲区,用两个管道可以实现全双工。
管道的创建:int pipe(int files[2]);参数为文件描述符,0为读,1为写;成功返回0,否则-1;写入的数据被读出就消失。然后就可以通过两个文件描述符files[0]、files[1]进行进程间的数据交互。
命名管道可保存为文件系统中,的特殊的设备文件,所以进程随时都可以通过命名管道进行I/O操作。
命名管道创建:通过命令:mkfifo fileName(还可以通过命令使用、删除FIFO);系统调用:int mkfifo(文件名, 管道文件权限),成功则返回文件描述符,否则返回-1。
网络中,主机间数据交互机制:套接字(socket)