
UNIX环境高级编程
文章平均质量分 76
对《UNIX环境高级编程》一书的重点进行分析,并通过程序来说明。
TODD911
热爱计算机
展开
-
《UNIX环境高级编程》笔记--伪终端
1.什么是伪终端伪终端对于一个程序来说,看上去像一个终端,但事实上并不是一个真正的终端。下图显示了使用伪终端时相关进程的典型结构。1.通常一个进程打开伪终端主设备,然后调用fork。子进程建立了一个新的会话,打开一个相应的伪终端从设备,将其文件描述符复制到标准输入、标准输出和标准出错,然后调用exec。伪终端从设备成为子进程的控制终端。2.对于伪终端从设备之上的用户进程原创 2014-03-10 16:57:30 · 8099 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--规范模式和非规范模式
1.规范模式规范模式很简单:发一个读请求,输入完一行后,终端驱动程序即返回。(终端的行缓冲应该就是通过终端IO函数来实现的)下列几个条件都会造成读返回。1.所要求的字节数已读到时,读返回。无需读一个完整的行。如果读了部分行,那么也不会丢失任何信息,下一次读从前一次读的停止处开始。2.但读到一个定界符时,读返回。在规范模式中下列字符为解释成行结束:NL、EOL、EOL2和EOF。原创 2014-03-08 20:24:12 · 2230 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--行控制函数、终端标识、终端窗口大小
1.行控制函数下列4个函数提供了终端设备的行控制能力,其中,参数filedes引用一个终端设备,否则出错返回,errno设置为ENOTTY。#includeint tcdrain(int filedes);int tcflow(int filedes, int action);int tcflush(int filedes, int queue);int tcsendbreak(i原创 2014-03-06 16:48:17 · 2682 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--特殊输入字符
POSIX.1定义了11个在输入是做特殊处理的字符。实现定义了另外一些特殊字符。下表摘要列出了这些特殊字符。POSIX.1允许禁用这些字符。若将c_cc数组中的某项设置为_POSIX_VDISABLE的值,则禁用相应的特殊字符。原创 2014-03-05 18:20:58 · 1783 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--终端IO
终端IO有两种不同的工作模式:1.规范模式输入处理。在这种模式中,终端输入以行为单位进行处理。对于每个读要求,终端驱动程序最多返回一行。例如,若shell把标准输入重定向到终端,2.非规范模式输入处理。输入字符并不组成行。终端设备是由一般位于内核中的终端驱动程序控制的。每个终端设备有一个输入队列和一个输出队列。大多数UNIX系统在一个称为终端行规程(terminal line原创 2014-03-04 20:45:51 · 1799 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--UNIX域套接字
1.非命名的UNIX域套接字UNIX套接字用于在用一台机器上运行的进程之间通信。UNIX套接字比因特网域套接字的效率更高。UNIX与套接字提供和数据报两种接口,UNIX域数据报服务是可靠的,就不会丢失消息也不会传递出错。UNIX域套接字是套接字和管道之间的混合物。为了创建一对非命名的,相互连接的UNXI域套接字,用户可以使用socketopair函数。#includeint so原创 2014-03-02 16:35:29 · 7503 阅读 · 1 评论 -
《UNIX环境高级编程》笔记--套接字选项,带外数据
1.套接字选项套接字机制提供两个套接字选项接口来控制套接字行为。一个接口用来设置选项,另一个接口允许查询一个选项的状态。可以获取或设置三种选项:1.通用选项,工作在所有套接字类型上。2.在套接字层次管理的选项,但是依赖于下层协议的支持。3.特定于某协议的选项,为每个协议独立。SUS仅定义了套接字层的选项。(1和2)可以采用setsockopt函数来设置套接字选项。#原创 2014-02-28 22:06:20 · 1911 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--套接字数据传输
套接字端点表示为文件描述符,只要建立连接,就可以使用read和write来通过套接字通信。在套接字描述符上采用read和write是非常有意义的,因为可以传递套接字描述符到那些原来设计为处理本地文件的函数。而且可以安排传递套接字描述符到执行程序的子进程,该子进程并不解释套接字。但是如果想指定选项,从多个客户端接受数据报或者发送带外数据,则需要采用六个传递数据的套接字函数中的一个。最原创 2014-02-28 14:42:26 · 2093 阅读 · 1 评论 -
《UNIX环境高级编程》笔记--套接字描述符、寻址、建立连接
1.套接字描述符套接字是通信端点的抽象。与应用程序使用文件描述符访问文件一样,访问套接字也需要用套接字描述符。要创建一个套接字,可以调用socket函数。#includeint socket(int domain, int type, int protocol); //成功返回套接字描述符,出错返回-1.domain确定通信的特性,包括地址格式。下表总结了POSIX.1指定的各原创 2014-02-25 09:26:30 · 3571 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--XSI IPC
1.XSI IPC有三种IPC我们称作XSI IPC,即消息队列,信号量和共享存储器,他们之间有很多相似之处。1.1.标识符和键每个内核中的IPC结构(消息队列,信号量或共享存储段)都用一个非负整数的标识符加以引用。标识符是IPC对象的内部名,为使多个合作进程能够在同一IPC对象上回合。需要提供一个外部名方案。为此使用了键(key),每个IPC对象都与一个键相关联,于是键就用作原创 2014-02-21 16:38:29 · 3355 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--管道
管道是UNIX系统IPC的最古老形式,并且所有的UNIX系统都提供此种通信机制。管道有下列两种局限性:a.历史上,它们是半双工的,现在某些系统提供全双工管道,但是为了最佳的可移植性,我们决不应预先假定系统使用此特性。b.它们只能在具有公共祖先的进程之间使用。通常一个管道由一个进程创建,然后该进程调用fork,此后父子进程之间可以使用该管道。(FIFO没有第二种局限性,UNIX域原创 2014-01-29 10:34:33 · 2640 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--存储映射IO
存储映射IO使一个磁盘文件与存储空间中的一个缓冲区相映射。于是当从缓冲区中取数据,就相当于读文件中的相应的字节;将数据存入缓冲区,则相应字节就自动写入文件,这样就可以在不是用read和write的情况下执行IO。这可以通过mmap函数实现。#includevoid *mmap(void *addr, size_t len, int prot, int flag, int filede原创 2014-01-27 16:27:49 · 2384 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--readv和writev函数
readv和write函数用于在一次函数调用中读,写多个非连续缓冲区。#includessize_t readv(int filedes, const struct iovec *iov, int iovcnt);ssize_t writev(int filedes, const struct iovec *iov, int iovcnt);//若成功则返回已读,写的字节数,若出错则原创 2014-01-26 12:55:43 · 8779 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--IO多路转换
读取原创 2014-01-26 10:45:45 · 1871 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--STREAMS
STREAMS(流)是system V提供的构造内核设备驱动程序和网络协议包的一种通用方法。流在用户进程和设备驱动程序之前提供了一条全双工通路。流无需和实际硬件设备直接会话,流也可以用来构造伪设备驱动程序,下图是一个简单流的基本构造。在流首之下可以压入处理模块,这个可以用ioctl命令实现,下图表示包含一个处理模块的流。各方框之间用两根带箭头的线连接,以突出流的全双工特性,原创 2014-01-23 13:49:46 · 3057 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--记录锁
记录锁的功能是:当一个进程正在读或者修改文件的某一个部分时,它可以阻止其他进程修改同一文件区。记录锁其实是字节范围锁,因为它锁定的只是文件中的一个区域,也可能是整个文件。1.fcntl记录锁SVR3通过fcntl函数增加了记录锁功能。fcntl函数的原型已经在以前给出,这边再重复一次。#includeint fcntl(int filedes, int cmd, .../* st原创 2014-01-22 16:21:16 · 4484 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--非阻塞IO
系统调用分成低速系统调用和其他系统调用两类。低速系统调用是可能会使进程永远阻塞的一类调用调用,他们包含:如果某些文件类型(例如管道,终端设备和网络设备)的数据并不存在,则读操作可能会使调用者永远阻塞。如果数据不能立即被上述相同类型的文件接受(由于在管道中无空间,网络流控制等),则写操作也会使调用者永远阻塞。在某些条件发生之前,打开某些类型的文件会被阻塞。(例如开打一个终端设备可能需要等原创 2014-01-22 09:34:00 · 2175 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--出错记录
与守护进程有关的一个问题是如何处理出错消息。因为它没有控制终端,所以不能只是简单地写到标准出错上,我们希望有一个集中的守护进程出错记录设施。自4.2BSD以来,BSD syslog设施得到了广泛应用。大多数守护进程使用这一设施。下图显示了syslog设置的详细组织结构;有三种方法产生日志消息:1.内核例程可以调用log函数。任何一个进程通过打开然后读/dev/klog设备就原创 2014-01-21 10:22:44 · 1824 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--守护进程
守护进程也被称为精灵进程(daemon),是生存期较长的一种进程。原创 2014-01-20 10:14:36 · 2782 阅读 · 1 评论 -
《UNIX环境高级编程》笔记-线程和信号
每个线程都有自己的信号屏蔽字,但是信号的处理原创 2014-01-17 21:59:39 · 2035 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--线程和fork
我们先来看一个程序:#include #include pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;void* th_fn(void* arg) { printf("start th_fn.\n"); pthread_mutex_lock(&mutex); printf("in th原创 2014-01-13 20:50:04 · 1766 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--线程的取消选项
有两个线程并没有包含在pthread_attr_t机构中,他们是可取消状态和可取消类型,这两个属性影响着线程在响应pthread_cancel函数调用时所呈现的行为。可取消状态属性可以是PTHREAD_CANCEL_ENABLE和PTHREAD_CANCEL_DISABLE,线程可以通过调用pthread_setcancelstate修改它的可取消状态。#includeint p原创 2014-01-12 14:30:26 · 1997 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--线程私有数据
线程私有数据时存储和查询与某个线程相关的数据的一种机制。把这种数据成为线程私有数据或线程特定数据的原因是,希望每个线程都可以独立地访问数据副本,并不需要担心与其他线程的同步访问问题。为什么要使用线程私有数据呢?原因有两个:1.有时候需要维护基于每个线程的数据,因为线程ID并不能保证是小而连续的整数,所以不能简单地分配一个线程数据数组,用线程ID作为数组的索引。即使线程ID确实是小而原创 2014-01-12 12:47:37 · 1851 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--同步属性
1.互斥量属性用pthread_mtexattr_init初始化原创 2014-01-12 10:22:37 · 2771 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--线程属性
在之前调用pthread_create函数的例子中,传入的参数都是空指针,而不是指向pthread_attr_t结构的指正,可以使用pthread_attr_t结构修改线程默认属性,并把这些属性与创建的线程联系起来。可以使用pthread_attr_init函数初始化pthread_attr_t结构。调用pthread_attr_init后,pthread_attr_t结构所包含的内容就是原创 2014-01-09 21:02:52 · 1650 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--线程的同步
多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图。1.互斥量可以通过使用pthread的互斥接口保护数据,确保同一时间只有一个线程访问数据,互斥量(mutex)从本质上说是一把锁,在访问共享资源前对互斥量进行枷锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁后,任何其他试图再次对互斥量进行加锁的线程将被阻塞知道当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有原创 2014-01-08 12:59:14 · 3168 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--线程的标识、创建和终止
1.线程标识就像每个进程都有一个进程ID一样,每个线程都有一个线程ID。进程ID在整个系统中是唯一的,但线程ID只在它所属的进程环境中有效。线程ID使用pthread_t数据类型来表示,实现的时候可以使用一个结构来表示pthread_t数据类型,所以可移植的操作系统实现不能将它比作整数处理。因此必须使用函数来对比线程ID进行比较。#include int pthread_eq原创 2014-01-06 09:46:45 · 2424 阅读 · 1 评论 -
《UNIX环境高级编程》笔记--sigsuspend函数
更改进程的信号屏蔽字可以阻塞所选择的信号,或解除对它们的阻塞,使用这种技术可以保护不希望由信号中断的代码临界区。如果希望对一个信号解除阻塞,然后pause等待以前被阻塞的信号发生,将如何呢?假定信号是SIGINT,实现这一点的一种不正确的方法是:sigset_t newmask,oldmask;sigemptyset(&newmask);sigaddset(&newmask, S原创 2013-12-15 10:25:40 · 5303 阅读 · 2 评论 -
《UNIX环境高级编程》笔记--sigsetjmp和siglongjmp函数
setjmp和longjmp函数用于非局部跳转,在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回。但是调用longjmp有一个问题,当捕捉到一个信号时,进入进行处理函数,此时当前信号被自动加到进程的信号屏蔽字中。这阻止了后来产生的这种信号中断该信号处理程序。如果用longjmp跳出信号处理程序,那么对此进程的信号屏蔽字会发生什么呢?POSIX原创 2013-12-14 14:50:27 · 5166 阅读 · 4 评论 -
《UNIX环境高级编程》笔记--sigaction函数
sigaction函数的功能是检查或修改指定信号相关联的处理动作,此函数取代UNIX早期版本使用的signal函数。#includeint sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);//若成功则返回0,出错则返回-1.参数signo是要检测或修改原创 2013-12-10 21:41:40 · 1859 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--信号集
1.信号集基本操作我们需要有一个能表示多个信号--信号集(signal set)的数据类型。POSIX.1定义了数据类型sigset_t以包含一个信号集,并且定义了一下五个处理信号处理信号集函数。#include int sigemptyset(sigset_t *set); //清除set中所有的信号int sigfillset(sigset_t *set); //使se原创 2013-12-08 19:05:38 · 1790 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--kill函数,raise函数,alarm函数,pause函数
1.kill函数和raise函数kill函数将信号发送给进程或者进程组,raise函数则运行进程向自身发送信号。#include int kill(pid_t pid,int signo);int raise(int signo);//若成功,则返回0,出错则返回-1.调用raise(signo);等价于调用kill(getpid(),signo);kill的pid参数有4种不同原创 2013-12-07 19:25:41 · 3178 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--可靠信号
在产生信号时,内核通常在进程表中设置某一种形式的标志。原创 2013-12-06 15:44:17 · 1813 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--中断的系统调用
在原创 2013-12-04 16:50:43 · 2260 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--信号及其处理函数signal
1.信号概念信号是软件中断,很多比较重要的应用程序都需要处理信号。信号提供了一种处理异步事件的方法。在有文件中,这些信号被定义为正整数。不存在信号为0的信号。很多条件可以产生信号:1.当用户按某些终端键时,引发终端产生的信号。在终端上按ctrl+c键,通常产生中断信号(SIGINT)。2.硬件异常产生信号:除数为0,无效的内存引用等等。这些条件由硬件检测到,并将其通知内核,然后原创 2013-12-03 15:13:09 · 1898 阅读 · 1 评论 -
《UNIX环境高级编程》笔记--孤儿进程组
POSIX.1将孤儿进程组定义为:该组中每个成员的父进程要么是该组的一个成员,要么不是该组所属会话的成员。一个进程组不是孤儿进程组的条件是:该组中有一个进程,其父进程在属于同一会话中的另一个组中。下面对孤儿进程组的产生进行检验:1.在一个具有作业控制的shell中,执行一个程序,该程序fork了一个子进程,其进程结构如下:2.父进程休眠5秒钟,这是一种让子进程在父进程终止前原创 2013-12-01 13:35:05 · 2646 阅读 · 7 评论 -
《UNIX环境高级编程》笔记--作业控制
作业控制允许在一个终端上启动多个作业(进程组),它控制哪一个作业可以访问该终端,以及哪些作业在后台运行,作业控制要求下面三种形式的支持:1.支持作业控制的shell。2.内核中的终端驱动程序必须支持作业控制。3.内核必须提供对某些作业控制信号的支持。我们可以键入一些特殊字符来影响前台作业:1.中断字符(ctrl+c)产生SIGINT。2.退出字符(ctrl+\)原创 2013-12-01 11:42:29 · 2023 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--tcgetpgrp,tcsetpgrp和tcgetsid函数
需要有一种方法来通知内核哪一个进程组是前台进程,这样,终端设备驱动程序就能了解将终端输入和终端产生的信号送到何处。#include pid_t tcgetpgrp(int filedes); //返回值:若成功则返回前台进程组的进程组ID,出错则返回-1.int tcsetpgrp(int filedes, pid_t pgrpid); //返回值:成功则返回0,出错则返回-1.函数t原创 2013-11-29 09:47:32 · 7136 阅读 · 3 评论 -
《UNIX环境高级编程》笔记--控制终端
会话和进程组有一些其他特性:1.一个会话可以有一个控制终端(controlling terminal),通常会话的第一个进程打开一个终端(终端设备或伪终端设备)后,该终端就成为该会话的控制终端,这通常是登录到其上的。2.建立与控制终端连接的会话首进程被称为控制进程。(controlling process)3.一个会话中的几个进程组可被分成一个前台进程组以及一个或者多个后台进程组。原创 2013-11-28 16:26:30 · 1848 阅读 · 0 评论 -
《UNIX环境高级编程》笔记--会话
会话(session)是一个或者多个进程组的集合。可以具有下图所有的安排,其中,一个会话中有3个进程组。上图的安排可能由以下形式的shell命令形成的:proc1 | proc2 &proc3 | proc4 | proc5进程调用setsid函数建立一个新会话。#include pid_t setsid(void); //若成功则返回进程组ID,出错则返回-1.原创 2013-11-26 20:58:47 · 1787 阅读 · 0 评论