随笔分类 -  APUE学习笔记

摘要:1 /** 2 *initserver.c 3 **/ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <syslog.h>10 #include <errno.h>11 12 int13 initserver(int type, const struct sockaddr *addr, socklen_t alen, int qlen)14 {15 int 阅读全文
posted @ 2012-10-05 15:18 leealways87 阅读(293) 评论(0) 推荐(0)
摘要:服务器端的程序名为ruptimed,服务名为ruptime,为客户端提供uptime服务,由于ruptime服务是用户自定义的服务,在调用getaddrinfo时出现如下错误:1 Servname not supported for ai_socktype我给getaddrinfo函数提供了主机名和服务名,但需要在系统中登记,即将ruptime和端口号写入/etc/services中(注意用户自定义的端口号不能小于1024,以免和系统已经存在的端口号冲突。程序名和服务名不必相同,服务名更像是程序的别名),将ruptime 4000/tcp添加到/etc/services文件末尾,这样就不会.. 阅读全文
posted @ 2012-10-03 00:38 leealways87 阅读(802) 评论(0) 推荐(0)
摘要:一、管道的特性 管道是UNIX系统IPC的最古老形式,并且所有UNIX系统都提供此种通信机制。但是管道有以下两种局限性: (1)半双工的(即数据只能在一个方向上流动),虽然有系统提供全双工的管道,但是为了可移植性,用户不能假设这种情况; (2)管道只能在具有公共祖先的进程之间使用。二、管道的创建管道由pipe函数创建:1 #include <unistd.h>2 int pipe(int filedes[2]);函数返回值:若成功则返回0,若出错返回-1。经由参数filedes返回两个文件描述符,filedes[0]为读而打开,filedes[1]为写而打开,也就是说filedes 阅读全文
posted @ 2012-09-09 21:35 leealways87 阅读(648) 评论(0) 推荐(0)
摘要:一、I/O模型首先,输入操作一般包含两个步骤:1、等待数据准备好(waiting for data to be ready)。对于一个套接口上的操作,这一步骤关系到数据从网络到达,并将其复制到内核的某个缓冲区。2、将数据从内核缓冲区复制到进程缓冲区(copying the data from the kernel to the process)。二、I/O模型类型其次了解一下五种I/O模型:1、阻塞I/O模型 最广泛的模型是阻塞I/O模型,默认情况下,所有套接口都是阻塞的。 进程调用recvfrom系统调用,整个过程是阻塞的,直到数据复制到进程缓冲区时才返回(当然,系统调用被中断也会返回).. 阅读全文
posted @ 2012-08-24 23:12 leealways87 阅读(1859) 评论(0) 推荐(0)
摘要:代码如下: 1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 int 6 main(void) 7 { 8 int i = 0; 9 pid_t fpid;10 printf("i\tson/pa\tppid\tpid\tfpid\n");11 12 for(i = 0; i < 2; i++) {13 fpid = fork();14 if(fpid == 0)15 printf("%d\tchild\t%4... 阅读全文
posted @ 2012-03-21 15:23 leealways87 阅读(301) 评论(0) 推荐(0)
摘要:互斥锁顾名思义,锁是用来锁住某种东西的,锁住之后只有有钥匙的人才能对锁住的东西拥有控制权(把锁砸了,把东西偷走的小偷不在我们的讨论范围了)。所谓互斥,从字面上理解就是互相排斥。因此互斥锁从字面上理解就是一点进程拥有了这个锁,它将排斥其它所有的进程访问被锁住的东西,其它的进程如果需要锁就只能等待,等待拥有锁的进程把锁打开后才能继续运行。在实现中,锁并不是与某个具体的变量进行关联,它本身是一个独立的对象。进(线)程在有需要的时候获得此对象,用完不需要时就释放掉。互斥锁的主要特点是互斥锁的释放必须由上锁的进(线)程释放,如果拥有锁的进(线)程不释放,那么其它的进(线)程永远也没有机会获得所需要的互斥 阅读全文
posted @ 2012-03-21 12:53 leealways87 阅读(491) 评论(0) 推荐(0)
摘要:GDB 是 linux 系统上常用的 c/c++ 调试工具,功能十分强大。对于较为复杂的系统,比如多进程系统,如何使用 GDB 调试呢?考虑下面这个三进程系统:进程 Proc2 是 Proc1 的子进程,Proc3 又是 Proc2 的子进程。如何使用 GDB 调试 proc2 或者 proc3 呢?实际上,GDB 没有对多进程程序调试提供直接支持。例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。 如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号并终止。那么该如何调试子进程呢?其实我们可以利用GDB的特点或者其他一 阅读全文
posted @ 2012-03-17 16:40 leealways87 阅读(251) 评论(0) 推荐(0)
摘要:根据APUE写线程代码阿,出现如下错误:1 test_pthread_create.c:(.text+0x2e6): undefined reference to `pthread_create'原因是没有链接libthread.a库文件,所以编译方法是:1 $ gcc -lpthread test_pthread_create.c 阅读全文
posted @ 2012-03-04 14:45 leealways87 阅读(117) 评论(0) 推荐(0)
摘要:#include <signal.h>#include <unistd.h>#include <stdio.h>#include "apue.h"static volatile sig_atomic_t sigflag;static sigset_t newmask, oldmask, zeromask;static voidsig_usr(int signo){ sigflag = 1;}voidTELL_WAIT(void){ if(signal(SIGUSR1, sig_usr) == SIG_ERR) err_sys(" 阅读全文
posted @ 2012-01-04 13:24 leealways87 阅读(675) 评论(0) 推荐(0)
摘要:Title: Implementing Software TimersBy: Don LibesOriginally appeared in the Nov. 1990 “C User’s Journal” and is alsoreprinted as Chapter 35 of “Obfuscated C and Other Mysteries”,John Wiley & Sons, 1993, ISBN 0-471-57805-3.http://www.wiley.com/compbooks/m3.html.——————————————————————— This column 阅读全文
posted @ 2012-01-04 10:41 leealways87 阅读(385) 评论(0) 推荐(0)
摘要:sleep使进程一直挂起,直到满足一下两个条件之一:1、睡眠时间到时;2、调用进程捕捉到一个信号,并从该信号处理函数返回;以下是APUE中实现sleep函数的源码,坑爹的我看了半天才明白,受伤。 1 #include "apue.h" 2 #include <signal.h> 3 4 static void 5 sig_alrm(int signo) 6 { 7 8 } 9 10 unsigned int11 sleep(unsigned int nsecs)12 {13 struct sigaction newact, oldact;14 sigset_t 阅读全文
posted @ 2012-01-03 21:03 leealways87 阅读(820) 评论(1) 推荐(1)
摘要:原文地址:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html一、信号生命周期从信号发送到信号处理函数的执行完毕对于一个完整的信号生命周期(从信号发送到相应的处理函数执行完毕)来说,可以分为三个重要的阶段,这三个阶段由四个重要事件来刻画:信号诞生;信号在进程中注册完毕;信号在进程中的注销完毕;信号处理函数执行完毕。相邻两个事件的时间间隔构成信号生命周期的一个阶段。下面阐述四个事件的实际意义:信号"诞生"。信号的诞生指的是触发信号的事件发生(如检测到硬件异常、定时器超时以及调用信号发送函数kill 阅读全文
posted @ 2011-12-29 23:16 leealways87 阅读(292) 评论(0) 推荐(0)
摘要:原文:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html一、信号及信号来源信号本质信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。信号来源信号事件的发生有两个来源:硬件来源 阅读全文
posted @ 2011-12-29 23:13 leealways87 阅读(323) 评论(0) 推荐(0)
摘要:wait和waitpid函数原型:1 #include <sys/wait.h>2 3 pid_t wait(int *status);4 pid_t waitpid(pid_t pid, int *status, int options);当进程正常或者异常终止时,内核就像其父进程发送SIGHLD信号,因为子进程终止是个异步信号,所以这种信号也是内核向父进程发的异步通知。对于这种信号,系统默认动作是忽略它,此时进程状态一直保存在内存中,直到父进程使用wait函数收集状态信息,才清空。用wait来等待一个子进程终止运行叫回收进程,如果一个子进程终止后,父进程没有调用wait函数收集 阅读全文
posted @ 2011-12-19 15:10 leealways87 阅读(602) 评论(0) 推荐(1)
摘要:fork函数:fork函数被调用一次,返回两次,子进程和父进程继续执行fork调用之后的指令。子进程是父进程的副本,也就是说子进程获得父进程数据空间、堆和栈的副本,但是两个进程是共享正文段(通常是read-only的)的。但是在具体的系统实现中,采用写时复制技术(Copy-On-Write, COW)。fork的一个特性是父进程的所有打开文件描述符都被复制到子进程中,也就是说父子进程的每个相同的打开描述符共享一个文件表项,而文件表项内容包含:文件状态标志、当前文件偏移量、指向该文件v节点表项的指针(在linux实现中,并没有v节点,而是使用i节点)。vfork函数:在子进程调用exec或exi 阅读全文
posted @ 2011-12-17 22:48 leealways87 阅读(891) 评论(0) 推荐(0)
摘要:寄存器变量:当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时间。为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU的寄存器中,使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率。寄存器变量的说明符是register。对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量,而循环计数是应用寄存器变量的最好候选者。 (1) 只有局部自动变量和形参才可以定义为寄存器变量。因为寄存器变量属于动态存储方式,凡需要采用静态存储方式的量都不能定义为寄存器变量,包括:模块间全局变量、模块内全局变量、局部static变量; (2) register是一个& 阅读全文
posted @ 2011-12-17 14:08 leealways87 阅读(535) 评论(0) 推荐(0)