随笔分类 -  Linux环境编程

学习linux api
摘要:1、概述 读写锁与互斥量类似,不过读写锁允许更高的并行性。互斥量要么是锁住状态,要么是不加锁状态,而且一次只有一个线程对其加锁。读写锁可以有三种状态:读模式下加锁状态,写模式下加锁状态,不加锁状态。一次只有一个线程可以占有写模式的读写锁,但是多个线程可用同时占有读模式的读写锁。读写锁也叫做共享-独占锁,当读写锁以读模式锁住时,它是以共享模式锁住的,当它以写模式锁住时,它是以独占模式锁住的。2、读写锁API 读写锁的数据类型为pthread_rwlock_t。如果这个类型的某个变量是静态分配的,那么可通过给它赋常值PTHREAD_RWLOCK_INITIALIZER来初始化它。获取和释放读... 阅读全文
posted @ 2013-01-09 16:17 Rabbit_Dale 阅读(4691) 评论(1) 推荐(1) 编辑
摘要:为了允许在线程或进程之间共享数据,同步时必须的,互斥锁和条件变量是同步的基本组成部分。1、互斥锁 互斥锁是用来保护临界区资源,实际上保护的是临界区中被操纵的数据,互斥锁通常用于保护由多个线程或多进程分享的共享数据。一般是一些可供线程间使用的全局变量,来达到线程同步的目的,即保证任何时刻只有一个线程或进程在执行其中的代码。一般加锁的轮廓如下:pthread_mutex_lock()临界区pthread_mutex_unlock()互斥锁APIpthread_mutex_lock(pthread_mutex_t *mutex);用此函数加锁时,如果mutex已经被锁住,当前尝试加锁的线程就会... 阅读全文
posted @ 2013-01-09 10:49 Rabbit_Dale 阅读(10754) 评论(3) 推荐(4) 编辑
摘要:消息队列中的消息结构可以由我们自由定义,具备较强的灵活性。通过消息结构可以共享一个队列,进行消息复用。通常定义一个类似如下的消息结构:#define MSGMAXDAT 1024struct mymsg{ long msg_len; //消息长度 long msg_type; //消息类型 long msg_data[MSGMAXDATA]; //消息内容};消息结构相关联的类型字段(msg_type)提供了两个特性:(1)标识消息,使得多个进程在单个队列上复用消息。(2)用作优先级字段,允许接收者以不同于先进先出的某个顺序读出各个消息。例子1:每个应用一个队... 阅读全文
posted @ 2013-01-08 12:14 Rabbit_Dale 阅读(1460) 评论(1) 推荐(1) 编辑
摘要:1、概述 消息队列可以认为是一个消息链表,System V 消息队列使用消息队列标识符标识。具有足够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息。在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达。SystemV 消息队列是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。可以将内核中的某个特定的消息队列画为一个消息链表,如下图所示:对于系统中没个消息队列,内核维护一个msqid_ds的信息结构:struct msqid_ds{ struct msqid_ds { struct . 阅读全文
posted @ 2013-01-07 11:03 Rabbit_Dale 阅读(2969) 评论(0) 推荐(2) 编辑
摘要:1、概述 System V IPC共有三种类型:System V消息队列、System V 信号量、System V 共享内存区。 System V IPC操作函数如下:2、key_t键和ftok函数 三种类型的IPC使用key_t值作为他们的名字,头文件<sys/types.h>把key_t定义为一个整数,通常是一个至少32位的整数,由ftok函数赋予的。函数ftok把一个已存的路径和一个整数标识符转换成一个key_t值,称为IPC键。函数原型如下:#include <sys/types.h>#include <sys/ipc.h>key_t ftok(c 阅读全文
posted @ 2013-01-07 09:19 Rabbit_Dale 阅读(4066) 评论(0) 推荐(0) 编辑
摘要:本章的内容是开发一个简单的、多用户数据库的C函数库。调用此函数库提供的C语言函数,其他程序可以读取和存储数据库中的记录。绝大部分商用数据库函数库提供多进程同时更新数据库所需要的并发控制,采用建议记录锁、B+树、动态散列实现数据库。1、函数库 开发类似ndbm函数库,增加了并发控制机制,从而允许多进程同时更新同一数据库。函数接口如下:1 #include "apue_db.h"2 DBHANDLE db_open(const char *pathname, int oflag, .../* int mode */); //返回值:若成功则返回数据库句柄,若出错则返回NULL3 阅读全文
posted @ 2012-12-27 11:18 Rabbit_Dale 阅读(1133) 评论(0) 推荐(0) 编辑
摘要:1、综述 伪终端对于一个应用程序而言,看上去像一个终端,但事实上伪终端并不是一个真正的终端。从内核角度看,伪终端看起来像一个双向管道,而事实上Solaris的伪终端就是用STREAMS构建的。伪终端总是成对地使用的,就好像是个管道的两端。一端的设备称为"主设备"(master),另一端的设备称为"从设备"(slave),每一对伪终端设备,例如/dev/ptys0和/dev/ttys0,就好像是通过一个管道连在一起,其"从设备"一端与普通的终端设备没有什么区别,而"主设备"一端则跟管道文件相似。伪终端的用途:(1)构 阅读全文
posted @ 2012-12-25 15:58 Rabbit_Dale 阅读(2664) 评论(0) 推荐(0) 编辑
摘要:终端I/O应用很广泛,用于终端、计算机之间的直接连线、调制解调器以及打印机等等。终端I/O有两种不同的工作模式: (1)规范模式输入处理:终端输入以行为单位进行处理,对于每个读要求,终端驱动程序最多返回一行。(默认模式) (2)非规范模式输入处理:输入字符并不组成行。 终端设备是由一般位于内核的终端驱动程序控制的,每个终端设备有一个输入队列和一个输出队列。如下图:可以检测和更改的终端设备特性都包含在termios结构中。该结构定义在<termios.h>struct termios{tcflag_t c_iflag; 输入标志tcflag_t c_oflag; 输... 阅读全文
posted @ 2012-12-25 10:31 Rabbit_Dale 阅读(921) 评论(0) 推荐(0) 编辑
摘要:本章主要介绍了基于STREAM的管道和UNIX域套接字,这些IPC可以在进程间传送打开文件描述符。服务进程可以使用它们的打开文件描述符与指定的名字相关联,客户进程可以使用这些名字与服务器进程通信。1、基于STREAMS的管道 STREAMS pipe是一个双向(全双工)管道,单个STREAMS管道就能向父、子进程提供双向的数据流。如下图所示:下面采用STREAMS管道实现加法协同进程实例,程序如下:View Code 1 1 #include <stdio.h> 2 2 #include <stdlib.h> 3 3 #include <unistd.h> 阅读全文
posted @ 2012-12-24 12:14 Rabbit_Dale 阅读(870) 评论(2) 推荐(0) 编辑
摘要:通过网络套接字可以使得不同计算机上运行的进程相互通信。1、创建套接字#include <sys/socket.h>Int socket( int domain, int type, int protocol);注意:AF_LOCAL域是AF_UNIX的别名,AF_UNSPEC域可以代表任何域。2、套接字通信是双向的,禁止套接字上的输入/输出#include < sys/socket.h>Int shutdown ( int sockfd, int how);3、处理字节序和网络字节序之间的轮换:#include< arpa/inet.h>Uint32_t h 阅读全文
posted @ 2012-12-23 22:16 Rabbit_Dale 阅读(1496) 评论(0) 推荐(0) 编辑
摘要:进程间通信(IPC)是指能在两个进程间进行数据交换的机制。现代OS都对进程有保护机制,因此两个进程不能直接交换数据,必须通过一定机制来完成。 IPC的机制的作用: (1)一个软件也能更容易跟第三方软件或内核进行配合的集成,或移植.如管道,在shell 下执行 ps –aux | grep bash。 (2)简化软件结构, 可以把一个软件划分多个进程或线程,通过IPC,集成在一起工作.如消息队列。 (3)让操作系统各个模块交换数据,包括内核与应用程序机制。 (4)提供进程之间或同一进程之间多线程的同步机制,如信号量。1、管道 管道是半双工的,数据只能向一个方向流动;需要双方通信时... 阅读全文
posted @ 2012-12-23 11:22 Rabbit_Dale 阅读(1079) 评论(0) 推荐(0) 编辑
摘要:1、非阻塞I/O对低速设备的I/O操作可能会使进程永久阻塞,这类系统调用主要有如下情况:(1)如果数据并不存在,则读文件可能会使调用者永远阻塞(例如读管道、终端设备和网络设备)。(2)如果数据不能立即被接受,则写这些同样的文件也会使调用者永远阻塞;(3)在某些条件发生之前,打开文件会被阻塞(例如以只写方式打开一个FIFO,那么在没有其他进程已用读方式打开该FIFO时);(4)对已经加上强制性锁的文件进行读、写;(5)某些ioctl操作;(6)某些进程间通信函数;非阻塞I/O调用open、read和write等I/O操作函数使上述的慢速系统调用在不能立即完成的情况下,立即出错返回。对一个给定的描 阅读全文
posted @ 2012-12-21 17:25 Rabbit_Dale 阅读(923) 评论(0) 推荐(0) 编辑
摘要:守护进程是在后台运行不受终端控制的进程(如输入、输出等),一般的网络服务都是以守护进程的方式运行。守护进程脱离终端的主要原因有两点:(1)用来启动守护进程的终端在启动守护进程之后,需要执行其他任务。(2)(如其他用户登录该终端后,以前的守护进程的错误信息不应出现)由终端上的一些键所产生的信号(如中断信号),不应对以前从该终端上启动的任何守护进程造成影响。要注意守护进程与后台运行程序(即加&启动的程序)的区别。创建守护进程的过程:1. 调用fork创建子进程。父进程终止,让子进程在后台继续执行。2. 子进程调用setsid产生新会话期并失去控制终端调用setsid()使子进程进程成为新会话组.. 阅读全文
posted @ 2012-12-20 16:12 Rabbit_Dale 阅读(1825) 评论(0) 推荐(0) 编辑
摘要:守护进程也称为精灵进程是一种生存期较长的一种进程。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。他们常常在系统引导装入时启动,在系统关闭时终止。unix系统有很多守护进程,大多数服务器都是用守护进程实现的,例如inetd守护进程。1、守护进程的特征用ps命令察看一些常用的系统守护进程,看一下他们和几个概念:进程组、控制终端和会话有什么联系。执行: ps–axj ,结果如下所示:从结果可以看出守护进程没有控制终端,其终端名设置为?,终端前台进程组ID设置为-1,init进程ID为1。系统进程依赖于操作系统实现,父进程ID为0的各进程通常是内核进程,它们作为系统自举的一部.. 阅读全文
posted @ 2012-12-20 10:01 Rabbit_Dale 阅读(2453) 评论(0) 推荐(0) 编辑
摘要:本章介绍了一个进程中多个线程之间如何保持数据的似有性及进程的系统调用如何与线程进行交互。1、线程限制: Single Unix定义了一线线程操作的限制,和其他的限制一样,可以通过sysconf来查询。和其它的限制使用目的一样,为了应用程序的在不同操作 系统的可移植性。 一些限制: PTHREAD_DESTRUCTOR_ITERATIONS: 销毁一个线程数据最大的尝试次数,可以通过_SC_THREAD_DESTRUCTOR_ITERATIONS作为sysconf的参数查询。 PTHREAD_KEYS_MAX: 一个进程可以创建的最大key的数量。可以通过_SC_THREAD_KEYS_... 阅读全文
posted @ 2012-12-19 15:14 Rabbit_Dale 阅读(1700) 评论(2) 推荐(1) 编辑
摘要:一个进程在同一时刻只能做一件事情,线程可以把程序设计成在同一时刻能够做多件事情,每个线程处理各自独立的任务。线程包括了表示进程内执行环境必需的信息,包括进程中标识线程的线程ID、一组寄存器值、栈、调度优先级和策略、信号屏蔽字、errno变量以及线程似有数据。进程的所有信息对该进程的所有线程都是共享的,包括可执行的程序文本、程序的全局内存、栈及文件描述符。 使用线程的好处:(1)为每种事件分配单独的线程、能够简化处理异步事件的代码;(2)多个线程自动地可以访问相同的存储地址空间和文件描述符;(3)将一个问题分解为多个程序,改善整个程序的吞吐量;(4)使用多线程改善交互程序的响应时间。 进... 阅读全文
posted @ 2012-12-18 17:49 Rabbit_Dale 阅读(1704) 评论(2) 推荐(1) 编辑
摘要:接着昨天学习Unix信号机制,信号内容挺多了,发了两天的时间才了解各大概,日后遇到问题需要多看几遍,掌握核心应用。7、sigaction函数sigaction函数的功能是检查或修改与指定信号相关联的处理动作或同时执行这两种操作,可以用sigaction函数实现signal函数。函数原型及结构参数如下: int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact); struct sigaction { void (*sa_handler)(int); void (*sa_sigac... 阅读全文
posted @ 2012-12-18 11:17 Rabbit_Dale 阅读(1599) 评论(2) 推荐(2) 编辑
摘要:1、signal函数 Unix系统的信号机制最简单的接口是signal函数,函数原型如下: #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); signum表示信号名称,handler取值常量SIG_IGN(忽略此信号)、常量SIG_DFL(执行默认动作)或者接到此信号后要调用的函数的地址(调用信号处理程序)。写个程序练习一下signal函数的使用,程序的功能是捕获子进程退出。程序如下:View Code 1 #i. 阅读全文
posted @ 2012-12-17 17:01 Rabbit_Dale 阅读(1058) 评论(0) 推荐(2) 编辑
摘要:信号时软中断,很多比较重要的应用程序都需要处理信号,信号提供了一种处理异步事件的方法。每个信号都一个名字,以SIG开头,在<signal.h>头文件中定义信号类型,都是正整数(信号编号)。 产生信号的条件:(1)当用户按某些终端键时,引发终端产生的信号。(2)硬件异常产生信号。(3)进程调用kill函数将信号发送给另外一个进程或进程组。(4)用户用kill命令将信号发送给其他进程。(5)检测到某种软件条件已经发送,并将其通知有关进程时候产生信号。 内核在信号出现时候处理方式有:(1)忽略此信号,(2)铺捉信号,(3)执行系统默认动作。Unix系统信号如下:其中SIGKILL和SIG 阅读全文
posted @ 2012-12-17 16:33 Rabbit_Dale 阅读(936) 评论(0) 推荐(1) 编辑
摘要:本章看后给人似懂非懂的感觉,主要是不知道实际当中如何去使用。通过前面几章的学习,每个进程都有一个父进程,当子进程终止时,父进程得到通知并取得子进程的退出状态。先将本章基本的知识点总结如下,日后再看时候好好总结一下。1、终端登录 介绍了有终端登录Unix系统的过程。通过init进程读文件/etc/ttys,fork一个子进程调用exec执行getty程序进行登录,当用户输入完用户名后,getty的工作完成了,然后调用login程序,类似execle("/bin/login","login","-p",username,(char *)0 阅读全文
posted @ 2012-12-17 12:18 Rabbit_Dale 阅读(916) 评论(0) 推荐(0) 编辑