- shell 是一种非凡的应用程序(命令行解释器),他为运行其余应用程序提供了一个接口。
- posix 标准了操作系统是什么样
- 每个过程都有一个工作目录(又叫当前目录),相对路径都是从工作目录开始解释。
- Ctrl+ D 是文件完结字符
- read 读指定字节数;fgets 是读取一行
- 三个过程管制函数:fork exec waitpid。waitpid【此函数获取信息,开释资源】父过程期待子过程终止,能够失去子过程何时终止。system 函数是在 exec 外包了一层。
- execlp 要求参数以 null 完结,换行符不能够
- 线程 id 只在它所属过程内起作用,在另一个过程中无意义,能够应用线程 id 援用相应的线程。
- 一个用户能够属于多至 16 个组
- ctrl+ c 中断键,ctrl+\ 退出键,等价于 kill 函数。kill(pid, SIGTERM)向另一过程发信号,发动信号的必须是该过程的所有者。
- (gdb)set follow-fork-mode child 使 gdb 进入子过程,事实证明不设置(默认调试父过程)这句无奈进入 pid== 0 的语句块。子过程 exit 后无奈再设置断点 gdb 信息失落,此时 run 可能启动的不是父过程而是孙过程。
- fork 会复制 fork 开始直到函数完结的代码【共享代码注释,但复制全副变量】
- 日历工夫:1970 至今秒数,time_t 类型用于保留这种工夫。
- 过程工夫:cpu 工夫,clock_t 类型用于保留这种工夫。
- 零碎 cpu 工夫是过程执行内核程序的工夫。执行用户指令的工夫是用户 cpu 工夫。两者之和是 cpu 工夫。时钟工夫【墙上钟工夫】,是过程运行的工夫总量,和过程数无关。time ls【ls 可换成任意程序名】查看工夫。
- clock_t times(struct tms* buf)胜利返回墙上钟工夫【必须应用相对值,做差】
- 库函数不肯定调用零碎调用。应用程序能够间接调用零碎调用,也能够通过 C 库函数调用零碎调用。
- ISO C 规范有 24 个头文件(包含 stdlib.h,stdio.h)。
- 接口即协定。
- 很多程序须要为门路调配存储区
- 守护过程:后盾运行且不与终端相连接的一种过程。
- 与文件或目录无关的选项用 sysconf 确定,与文件或目录无关的选项用 pathconf,fpathconf 确定。
- unix 零碎的大多数文件 I / O 只须要用到 5 个函数:open close read write lseek,都是不带缓冲的 I /O。不带缓冲指的是 read write 都调用内核的一个零碎调用。不带缓冲的 io 不是 iso c 的组成部分,是 posix 的组成部分。
- 对内核而言,所有的关上的文件都通过文件描述符(非负整数)援用。0 1 2 别离是输出 输入 谬误 的描述符。文件描述符变动范畴 0 -OPEN_MAX(示意每个过程能够关上 OPEN_MAX 个文件)。
- open 函数:int fileId【返回最小的未用文件描述符数值】= open(tmpPtr->_fileName【文件名】,O_RDWR【读、写关上】|O_CREAT【如果不存在则创立】, 0666【配合 O_CREATE 指定新文件拜访权限】);
- close(fileId); 敞开文件同时开释过程加在该文件上的所有记录锁。过程终止时内核主动敞开它关上的文件。
- 返回文件偏移量【偏移量始终存在,读、写操作从它指向的地位开始】=lseek(fileId,offset【每一个关上的文件都有一个以后文件偏移量,默认 0,除非指定 O_APPEND】,SEEK_SET【将偏移量设为文件开始处 offset 字节】)
- lseek 返回 - 1 阐明文件描述符对应的文件是管道、fifo 或网络套接字。某些设施容许负的偏移量。
- od -c 文件名【- c 示意以字符形式打印文件内容】ls -ls 查看文件占用多少个磁盘块
- nRead【返回读到字节数】= read(flag_fd【文件描述符】, buffer【读取数据到 buffer 中】, length【一次读取字节数】)【胜利返回前,偏移量减少读到的字节数】
- int bytes_write【返回写入字节数】= write(fileHandle,ptr,writeSize【写入字节数】)【写操作从以后偏移量开始,胜利后偏移量主动减少写入字节数】
- 测量文件读写因为缓存机制,在第一次之后可能不精确。
- 每个过程都有一张关上文件描述符表 -> 文件表(以后文件偏移量)->v 节点信息
- 可能有多个文件描述符指向同一文件表项,多个文件表项指向一个 v 节点表。多过程读同一个文件没有问题,然而写同一个文件会有问题 -> 原子操作。
- open 中用 O_CREAT 和 O_EXCL 能够将测试和创立合并为一个原子操作。原子操作指多步组成的操作要么执行完所有步骤,要么一步也不执行。
- 先 lseek 再 write 不可能是原子操作。两个函数间内核能够挂起过程。
- pread(…, off_t offset) pwrite(…, off_t offset) 相当于顺序调用 lseek 和 read,与顺序调用的区别:无奈中断、不更新文件指针
- O_APPEND 形式关上文件,每次 write,文件偏移量主动定位到文件尾。
- 新的文件描述符 = dup(int filedes) dup2(int filedes【被复制】,int filedes2【指定数值】) 复制现存的文件描述符,与参数 filedes 共享同一个文件表项。fcntl(..)也能够复制文件描述符。
- sync 将块缓冲区排入写队列,不等理论写磁盘。fsync 对繁多文件起作用,等写磁盘完结返回,更新属性。fdatasync 只影响文件的数据局部。
- fcntl(..)返回值和命令无关,能够返回文件状态,文件描述符。能够批改文件状态。
- 5<>temp 示意在文件描述符 5 上关上文件供读写。
- 终端 I / O 是 ioctl 的最大应用方面。
- digit1 > &digit2 示意要将 digit1 重定向至描述符 2 的同一个文件。
- shell 从左到右解决命令
- struct stat sA【stat 构造体蕴含磁盘号,所有者,拜访批改工夫等属性】; int retA【返回小于 0 示意文件不存在】= stat(fileNameA.c_str(),&sA【stat 函数将填写 sA】); ls - l 就是应用的 stat(…)函数
- lstat(…)的加强性能是检测符号链接
- 文件类型信息蕴含在 stat 构造的 st_mode 成员中,有上面几种类型。
一般文件【蕴含某种数据的文件,数据是文本还是二进制对内核而言无区别,对文件内容的解释由解决该文件的应用程序进行。例外:二进制可执行文件恪守内核了解的对立格局】
目录文件【蕴含其余文件的名字以及指向与这些文件无关信息的指针】
块设施文件【磁盘,提供对设施带缓冲的拜访】
字符设施文件【键盘,提供对设施不带缓冲的拜访】
FIFO 又名管道文件,shell 里的竖线 |【用于过程间通信】
套接字【这种文件用于过程间的网络通信,也可用于一台机上过程间的非网络通信】
符号链接【这种文件类型指向另一个文件】
- 过程间通信(IPC)对象也示意为文件:音讯队列、信号量、共享存储对象。
- 执行一个程序时 exec(…)会保留无效用户 ID 和无效组 ID。通常无效 ID== 理论 ID。
- 当文件的无效用户 ID 设置为文件所有者 ID 时,如果所有者为 root,即便被一个普通用户执行,该过程也具备超级权限。
- 文件拜访权限:第一个规定是咱们用名字关上一个文件时,对该名字蕴含的每一个目录,包含她可能隐含的当前工作目录 (./) 都应具备执行权限。对文件有适当的权限,取决于以何种形式关上。
- 对目录的读权限使咱们能够取得该目录所有文件名列表。对目录的执行权限使咱们能够通过该目录,也就是【搜寻】该目录,寻找一个特定的文件名。
- 创立文件须要对目录有写权限和可执行权限。删除文件须要对目录有写和可执行权限【理论是缩小文件 i 节点的一个连接数而已,文件自身还存在】,对文件自身不须要有读、写权限【删除对文件自身没读没写】。
- 新文件的用户 ID 设置为过程的无效用户 ID。新文件的组 ID 能够是:1. 过程的无效组 ID。2. 它所在目录的组 ID。
- access(pathname, mode)按理论用户 ID,和理论组 ID 进行拜访权限测试。只有 root 能 chown.
- umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 设置过程的文件模式创立屏蔽字
creat(“bar”, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH)
先后运行下面两行的运行后果 -rw——- bar
chmod(“bar”, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) fchmod(fildes, mod)
运行后果 -rw-r–r– bar
- -rw-rwSrw- S 示意设置组 ID【无效用户 ID 和组 ID】位已设置【无效用户 ID 变成文件所有者的 ID】,同时,组执行位则未设置。
- linux 替换区 ==windows 下虚拟内存
- chmod a+t 目录 设置粘住位
- 粘住位:可执行程序注释正本保留在替换区。目录设置了粘住位,只有对目录有写权限加上 1. 领有文件;2. 领有目录;3.root 三种之一 才能够删除或更名目录下的文件。
- chown fchown lchown 更改文件用户 ID
- truncate(pathnane, length) ftruncate(filedes, length) 截断文件或创立空洞
- 磁盘可分为多个区,不同的区有不同的文件系统。
- 目录项【目录 / 文件名】->i 节点 -> 理论数据块。多个目录项能够指向同一个 i 节点,例如软连贯和目录自身指向的是同一块数据,就应该指向的是同一个 i 节点。mv 只更改目录名,不挪动理论数据。
- link(existpath, newpath)创立一个新的目录项,减少链接数;unlink(pathname)删除目录项,将 pathname 所援用的文件链接数减 1. 目录项删除后看不见文件,但文件仍有可能占据磁盘空间直至被内核删除。
- ./a.out & 示意后盾运行
- 如果关上文件的过程数和链接数同时为 0,内核会删除该文件。
- remove(pathname)解除对一个目录或文件的链接。rename(oldname, newname)
- 一般目录项和文件自身的关系是硬链接,她间接指向文件的 i 节点。符号链接是指向一个文件的间接指针,能够跨不同的文件系统。要留神函数是否追随符号链接。
- symlink(actualpath, sympath)创立符号链接。readlink(pathname, buf, bufsize)关上链接自身,并读链接中的名字。
- ls -lt 默认按文件批改工夫排序,- u 按拜访工夫,- c 按更改状态工夫。utime(pathname, times)更改文件的拜访和更改工夫。
- mkdir(pathname, mode)创立一个新的空目录。rmdir(pathname)删除一个空目录。
- DIR opendir(pathname) struct dirent readdir(DIR *dp) chdir(…)【当前工作目录是过程的一个属性,chdir 只影响过程自身】fchdir(…) getcwd(…)取得残缺绝对路径
- 规范 I / O 库【ISO C 规范】文件操作围绕文件描述符,也能够了解成围绕流(stream)。当用规范 io 关上或创立一个文件时,咱们已使一个流与文件关联。规范 IO 最终都要调用 read,write。
- FILE 构造蕴含:文件描述符、缓冲区指针、缓冲区长度、以后缓冲区字节数以及出错标记。文件指针是 FILE*
- 规范输入输出的文件指针是 stdin,stdout,stderr。io 库提供缓冲的目标是缩小应用 read 和 write 的调用次数。规范 io 函数通常调用 malloc 取得缓冲区。
- setbuf(FILE , buf, mode ,size)更改缓冲类型。fflus(FILE fp)此函数使该流所有未写的数据都被传送至内核。
- FILE *fdopen(filedes, type)使已有的文件描述符和流关联。
- FILE freopen(pathname, type, FILE restrict fp)在一个指定的流上关上文件,若流已关上,先敞开流。个别用于将指定文件关上为一个预约义的流:输出,输入,谬误。
- FILE *fopen(pathname, type【r+b,加号示意读和写】)关上一个指定的文件,b 辨别文本和二进制,对 unix 无用。cache 中用的都是 open
- int fclose(FILE *fp)敞开一个关上的流。
- 读写构造 fread fwrite
- 一次一行 fgets fputs
- 一次一个字符 getc(FILE fp) fgetc(FILE fp) getchar(void) getchar 等价于 getc(stdin)。出错或达到文件尾,三个函数返回同样的值,为了辨别须要 ferror(FILE fp) feof(FILE fp) void clearerr(FILE *fp)
- int ungetc(int c, FILE *fp)将字符再压送回流中。
- 一次一个字符输入函数 putc(int c, FILE) fputc(int c, FILE) putchar(int c)
- 调用函数工夫长于调用宏;一次零碎调用比一般函数调用更费时间。
- 每次一行 io 的函数:char fgets(buf,n,FILE)从指定流读。char gets(buf)从规范输出读。输入:fputs(str, FILE) puts(str)
- 二进制 IO:size_t fwrite(&struct[2], sizeof(struct), 4, FILE* fp) 将一个数组的第 2 - 5 号元素写在一个文件上
- fread(..) 只能解决对立零碎上的数据,异构零碎通过网络互连时不行,不同零碎间替换二进制数据须要应用较高级的协定。
- 定位流:ftell(FILE) fseek(FILE, offset, whence【SEEK_SET】) rewind(FILE*) fgetpos(..) fsetpos(…) 文件描述符是用 lseek
- int fileno(FILE fp)取得文件描述符,FILE tmpfile(void)创立临时文件
- $TMPDIR=.. ./a.out 在程序名前指定环境变量
- int printf(format,…)将格式化数据写到规范输入。vprintf(format, va_list arg) vfprintf(…,va_list arg) vsprintf vsnprintf 可变参数表(…) 变成了 arg
- int fprintf(FILE* fp, format, …)写至指定的流
- int sprintf(buf, format)将格式化的字符串写入数组 buf 中,在数组尾端主动加 null 字节
- int snprintf(buf, size_t n,format, …) 与 sprintf 根本一样,n 指定了缓冲区长度,超过就抛弃防止溢出
- int scanf(format, …) sscanf(cmdline【源】, “%s %s”, opt[0], opt[1]【目标】)
- int fscanf(FILE *fp, format, …)
- int sscanf(buf, format, …) vscanf(format, va_list arg)等等
- struct passwd getpwnam(const char name)获取口令文件项
- struct tm 构造用于保留工夫的年月日的模式。
- gettimeofday(struct timeval *res, NULL)微秒级
- time_t time(time_t* calptr)返回以后工夫,calptr 不空,工夫值放其中。
- struct tm localtime(const time_t ptr)他和 gmtime(..)的区别是他把日历工夫转换为本地时区工夫,gmtime 转换成国际标准工夫。
- time_t mktime(struct tm* ptr)以本地工夫作为参数,将其转换为 time_t 值【日历工夫:1970 至今】。
- char asctime(struct tm)返回指向年月日字符串的指针。char ctime(time_t * prt)返回指向日历工夫的指针。
- size_t strftime(…)按格局管制工夫字符串
- timeval 指定秒和微秒、timespec 指定秒和纳秒
- 失常终止一个程序:exit()默认蕴含敞开流操作【FILE 存储区清 0】在 main 中 exit(0)等价于 return(0)
- int atexit(void (*func)(void))注销的函数会被 exit 函数以相同的顺序调用。
- 内核执行程序的惟一办法是 exec。过程被迫终止的惟一办法 exit【显式或隐式】。非被迫的须要给一个信号终止。
- extern char **environ 环境指针 getenv putenv 拜访特定环境变量
- a.out 的符号表段、调试信息段、动静共享库链接表段不装载到过程执行的程序映像中。size a.out 报告注释段、数据段、bss 段的长度
- cc -static hello1.c 阻止应用共享库。cc 默认应用共享库
- void* malloc(size_t size)存储区初始值不确定
- void* calloc(size_t nobj, size_t size)为指定数量指定长度的对象调配存储区,初始化为 0
- void realloc(void ptr, size_t newsize)更改以前的长度,新增局部初始值不确定,老局部保留内容。
- void free(void* ptr)
- goto 语句不能逾越函数,setjump longjmp 能够解决嵌套调用中出错状况【否则只能查看返回值逐层返回麻烦】。在心愿返回的地位 int setjmp(jmp_buf env【env 为全局才多个函数可见】), 出错地位 int longjmp(env,8)。
- “str1” “str2″ 等价于 ”str1str2″。为 IO 库调配缓冲区应全局动态或动静 alloc 调配。
- 编译器进行优化时,它有时会取一些值的时候,间接从寄存器里进行存取,而不是从内存中获取,这种优化在单线程的程序中没有问题,但到了多线程程序中,因为多个线程是并发运行的,就有可能一个线程把某个公共的变量曾经扭转了,这时其余线程中寄存器【线程各自有寄存器】的值曾经过期,但这个线程自身还不晓得,认为没有扭转,仍从寄存器里获取,就导致程序运行会呈现未定义的行为。
- 主动变量不想回滚,能够定义为 volatite【易失】属性。易失属性通知编译器不要优化,在其余中央会扭转值,优化可能将这个变量始终放到寄存器中。
- int getrlimit(int resource, struct rlimit *rlptr) setrlimit 能够查问和更改资源限度。shell 中的 ulimit。
- getpid getppid【取得父过程 id】getuid geteuid getgid getegid【无效组 id】
- pid_t fork(void) fork 返回两次 clone,父返子,子返 0. 父子过程执行 fork 之后的代码,父子共享注释不共享数据,共享文件表和 i 节点。写时复制 (copy-on-write) 写时复制,只读时共用。
- vfork 在子过程调用 exec 或 exit 之前,他在父过程的空间中运行,调用 exec 或 exit 之后父过程才持续运行。
- 规范 IO 库 printf 是带缓冲的。规范输入连到终端是行缓冲【打印】,否则是全缓冲。定向到文件是全缓冲
- 信号可由过程本身产生【abort】、其余过程【kill(pidid,sig)】或内核产生。
- 父过程提前终止的的子过程由 init【init 中默认有 wait】过程领养。内核为每个终止的子过程保留了一定量的信息,父过程用 wait 或 waitpid 失去这些信息。
- 一个长期运行的过程 fork 很多子过程,除非手动 wait,否则会呈现很多僵死过程。
- pid_t wait(int statloc) pid_t waitpid(pid_t pid【期待 pid 号过程】, int statloc【指向终止状态】, int options)【胜利返回过程 id、0、失败返回 -1】。如果收到 SIGCHLD 信号调用 wait,能够立即返回,如果任意时刻调 wait,可能会阻塞直到有一个子过程终止。
- wait3 wait4 比 waitpid 多了一个性能是最初一个参数会返回所有子过程应用资源状况的汇总。
- 竞争条件:多过程解决共享数据,数据的后果和解决程序无关。父等子死用 wait,子等父死【轮询】while(getppid() != 1) sleep(1); 等于 1 是 init 过程 id。为 1 阐明父过程死了,被 init 接管了。
- exec 不创立新过程,过程 ID 不变。exec 只是用一个全新的程序替换以后过程的注释、数据、队、栈。execl execv execle execve execlp execvp
- 所有.c 文件查找字符串 abort 的指令 $ grep abort .//.c
- 任何时候都能够调用 int setuid(uid_t uid)做下两种操作:无效用户 ID= 理论用户 ID;无效用户 ID= 保留的设置用户 ID【exec 复制无效用户 ID 得来的(个别是文件所有者?)】。设置用户 ID 的程序,fork 后,exec 之前要改回一般权限,不应应用 system 函数。
-
suspend $fg 作业控制
- shell 中 awk 理论是 shell 先 fork->exec(awk)->wait 来运行的。
- char* getlogin(void)获取登录名。找到运行该程序的用户登录名 getpwuid(getuid())
- 网络登录 telnetd 过程 fork,父负责网络连接的通信,子执行 login,父子间通过伪终端相连接。
- 过程组是一个或多个过程的汇合。getpgid setpgid 设置指定过程或调用过程的组 ID。
- 会话是一个或多个过程组的汇合。过程调用 pid_t setsid(void)建设一个新会话。过程是首过程、组长、断开所有管制终端。pid_t getsid(pid_t pid)返回会话首过程的过程组 ID。
- secureCRT 是终端,对应前台过程组【终端(终端也是文件描述符)关联的过程】,管制过程组【shell】,后盾过程组【& 让其后盾运行】,加在一起是会话。
- 一个作业是几个过程的汇合,通常是一个过程的管道线。vi main.c【前台启动了一个作业】pr *.c | lpr & | make all &【后盾启动了两个作业,两个作业调用的所有过程都后盾运行】
- 终端驱动程序产生信号进而影响前台过程组的办法:中断字符 ctrl+C 退出字符 ctrl+\ 挂起字符 ctrl+Z。能够用信号使后台作业暂停,fg %1 使 1 号作业转为前台作业
- 过程属于过程组,过程组属于一个会话,会话可能有也可能没有管制终端。前台过程组 ID 是终端的属性,不是过程的属性。
- 管道线的最初一个过程是 shell 的子过程,执行管道的其余命令都是最初一个过程的子过程。前端过程组 ID==sessionID 时阐明他是后盾过程。
- 不是孤儿过程组的条件:该过程组中有一个过程,其父过程属于同一个会话的另一个组。
- 信号 SIGKILL SIGSTOP 不能疏忽,不能捕获。
- core 文件复制过程终止时的存储映像。
- kill 命令和 kill 函数只是将一个信号送给一个过程或组,过程是否终止取决于信号的类型,以及过程是否安顿了捕获该信号。$kill -USR1 7216
- void (signal(int signo, void (func)(int)))(int)胜利返回信号以前的解决配置,失败返回 SIG_ERR。不扭转信号的解决形式,就不能确定信号以后的解决形式。func 指定 SIG_IGN 或 SIG_DEL 示意疏忽或默认解决。
- exec 使捕获生效,捕获函数的地址可能无意义。
- 过程捕捉到信号执行信号处理函数 func,执行完后执行产生信号时正在执行的代码【pause 函数能使过程挂起直到捕捉到一个信号】。解决第一次信号后是否将信号动作复位为默认值?
- read write 局部数据时被中断算胜利还是失败能够抉择。
- 在信号处理程序中调用一个不可重入函数,后果是不可预感的。
- raise(int signo) == kill(getpid(), int signo) 过程将信号发送给其余过程须要权限。向一个不存在的过程发空信号,kill 返回 -1.
- 过程 ID 会从新应用。
- signal 函数的语义与实现无关,最好应用 sigaction 函数。sigaction(signo【要检测或批改的具体动作的信号编号】, &act【非空则批改其动作】, &oact【非空则返回信号的上一个动作】)
- sigemptyset(&act.sa_mask)【初始化由 set 指向的信号集革除其中所有信号】
- 在解决一个给定的信号时,如果这种信号再次发生,通常并不将他们排队,会被阻塞到对前一个信号处理完结为止。阻塞完结后内核只传递这种信号一次。【屏蔽字为 0 代表没有信号阻塞,执行哪个信号的处理函数屏蔽哪个信号】
- unix 低速零碎调用阻塞期间【磁盘 IO 个别不阻塞】如果承受到一个信号,则该低速零碎调用被中断。
- void abort(void)使异样程序终止。子过程终止会向父过程发送 SIGCHLD 信号。sig2str str2sig 是信号编号和信号名互相转换函数。
- 多线程程序在单处理器运行依然能改善响应工夫和吞吐量。
- 线程 ID 只在它所属的过程环境中无效,因而能够不惟一。
- pthread_t pthread_self(void)取得本身线程的 ID。主线程能够用线程 ID 管制哪个线程解决哪些作业。新线程和主线程之间有竞争,应用主线程返回的线程 id 并不平安。线程 ID 如果很长那预计是地址。
- 如果任一线程调用 exit,_Exit,_exit 整个过程就会终止。线程终止形式:1. 启动函数返回。2 被同过程其余线程勾销【线程能够疏忽勾销】。3 pthread_exit
- void pthread_exit(void rval_ptr) int pthread_join(pthread_t thread, void* rval_ptr【保留线程的终止状态】)【阻塞直到线程返回】
- 线程外面申明的货色别往出带。线程从线程函数返回终止,清理程序就不被调用。waitpid==pthread_join。pthread_detach 使线程拆散【对线程终止状态不感兴趣】,拆散线程终止时资源被回收,拆散的线程无奈 pthread_join。
- 加锁的一种场景:对援用计数加 1、减 1 以及查看是否为 0 之前都要锁住互斥量。【援用数相似文件的 link】
- 读写锁以读模式锁住是共享模式【并发读】,以写模式锁住是独占模式【单独写】。
- 线程的虚拟地址空间是多个线程共用,如果线程多,会不够用。递归类型互斥量能够递归加锁。
- 线程和信号都波及函数可重入的问题。信号:捕获函数如果向全局数据写会错。线程:多个线程同时调用同一函数。每个线程有各自的信号屏蔽字。信号处理函数过程内共享。
- errno 被从新定义为线程公有数据。键用来爱护线程公有数据。
- 蕴含多线程的过程 fork 时只有 fork 的线程被复制进子过程,锁的状况无法控制,如果马上 exec 就能够防止。
- pread(…)使偏移量的设置和数据读取成为一个原子操作。
- ps -a【显示其余用户所领有的过程状态】x【没有管制终端的过程状态】j【会话 ID、过程组 ID。。】
- 创立守护过程两次 fork,就不是会话首过程,不会获得管制终端。fork 保障子过程不是过程组组长,能够 setsid。
- lockfile(fd)对文件加锁 lockf(lockfd, F_TLOCK, 0L)能够确保只有一个守护过程运行。
- 低速零碎调用是可能会使过程永远阻塞的一类零碎调用。
- 非阻塞 IO:操作无奈实现,立刻出错返回【不停在那,以便进行下一步解决,相似 trylock 试加锁】。两种办法指定描述符为非阻塞 IO:open 时 O_NONBLOCK;fcntl(fd, cmd, &lock)关上 O_NONBLOCK 标记。
- 记录锁 == 字节范畴锁:当一个过程读或批改文件某局部时,能够阻止其余过程批改同一文件区。有些零碎中文件的最初状态取决于写该文件的最初一个过程。
- 同一过程可对同一字节范畴反复加锁,新锁换老锁。能够测试另一个过程是否对某记录加锁。
- 锁是与过程、文件两者相关联的。fork 出的子过程不继承父过程对文件的锁【防止父子同时写一个文件】。exec 新程序继承原程序的锁。
- 某些 unix 提供零碎调用跟踪个性。
- STREAM:结构内核设施驱动程序和网络协议包的一种通用办法。
- IO 多路转接【两个描述符】:执行阻塞 read,阻塞是对整个过程阻塞,如果多个通路【个别是有限循环读、写】想要互相不影响,就得 fork 多个过程,每个过程解决各自的文件描述符。用非阻塞 read 轮询描述符耗费 cpu。
- IO 多路转接思维:结构一张描述符表,调用一个函数,直到表中描述符中的一个曾经筹备好 IO 时,该函数返回,通知过程哪些描述符能够 IO。次要用于终端 IO 和网络 IO。select(0, NULL, NULL, NULL, &tv)相当于 sleep 了,准确到微秒。
- 异步 IO:根本思维, 通知内核,当一个描述符已筹备好能够进行 IO 时,用一个信号告诉它【它指应用程序】。零碎 V 异步 IO 调 ioctl 设置信号处理,只对 STREAMS 设施和 STREAMS 管道起作用。BSD 异步 IO 设置信号 SIGIO 处理程序,调 fcntl 设置 O_ASYNC 文件为异步 IO。只对终端和网络描述符无效。
- 存储映射 IO:【将一个给定文件映射到一个存储区域】unsigned char mmapBuf = (unsigned char)mmap(NULL【区域起始地址】, fileSize, PROT_READ【映射区可读】, MAP_SHARED ,fd【被映射文件】, 0【映射字节在文件中起始偏移量】) munmap((char*)mmapBuf, fileSize)【解除映射】msync 冲洗到磁盘
- IPC【InterProcess Communication】:各种管道、音讯队列、信号量、共享存储、套接字、STREAMS【仅后两种反对不同主机过程间通信】
- 管道:半双工【数据只能在一个方向上流动】;只能在公共先人的过程间应用,通常 fork 后父子间应用。int pipe(int filedes[2]) fork 后 f[0]<-【内核主动?】-f[1] 有两份,各敞开一个
- sh -c cmdstring 示意 shell 将扩大字符串中的特殊字符【*.c】。
- ${PAGE:-more}如果 PAGE 已定义,应用,否则用 more。
- 对管道规范 IO 默认全缓冲。
- 通过 FIFO【命名管道】不相干的过程也能替换数据。int mkfifo(pathname, mode_t mode)相似于创立一般文件。
- 创立 IPC 构造:msgget semget shmget 要指定一个键 key_t。ftok 可由一个路径名和我的项目 ID 产生一个键 key_t ftok(path, id)
- msgctl semctl shmctl 批改 uid、gid、mode 三种 IPC 都有内置限度,可通过配置内核批改。ipcs 查看 ipcrm 删除
- msgrcv 能够是非先进先出
- 信号量的值代表对应资源是否能够应用。semop(_ID, buf[]【数组中操作要么都执行,要么都不执行】, 1)示意期待信号量、开释资源、获取资源。semctl 取信号量信息、设置信号量信息。
- 应用信号量【实际上是同步原语而不是 IPC】,先创立一个蕴含一个成员的信号量汇合,信号量值赋初值 1. 分配资源时 sem_op 为 - 1 调用 semop,开释资源 sem_op 为 1 调用 semop。每次设置 SEM_UNDO,以解决过程终止还有未开释资源的状况。
- shmget 既能够创立,也能够援用已有的【msgget 一样】。shmctl IPC_RMID 缩小援用数,不真正删除。shmid 和 pickey 不一样,shmget 返回值是 shmid。shmdt 脱接不删除,援用数减一。
- 套接字用于不同计算机上的过程互相通信,其它过程运行地位通明。能够采纳许多网络协议,TCP/IP 常见。
- 创立一个套接字 int socket(int domain【例如 ipv4internet 网域】, int type, int protocol)返回套接字文件描述符。
- int shutdown(int sockfd, int how)禁止套接字上的输入输出。uint32_t htonl(uint32_t hostint32)等进行处理器字节序和网络字节序的转换。
- inet_pton(AF_INET, host.c_str(), &m_addr.sin_addr)将文本字符串转换成网络字节序的二进制地址
- poll select 函数能查看文件描述符的状态,用来决定是否对文件描述符执行某种操作。
- setsockopt(_sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len)
- int fattach(int fileds, const char* path)使 STREAMS 管道和文件系统中的一个名字关联。
- unix 域套接字用于同一机器上过程间通信。int ssocketpair(int domain, int type, int protocol, int sockfd[2])
- 终端 IO:函数 tcgetattr tcsetattr 终端 IO 管制函数大多 tc 结尾
- 很多数据库实现都采纳两个文件:索引文件和数据文件。