随笔分类 -  进程间通信IPC

摘要:1、概述 系统调用mmap通过映射一个普通文件实现共享内存。System V 则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信。也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件。执行过程是先调用shmget,再调用shmat。对于每个共享的内存区,内核维护如下的信息结构,定义在<sys/shm.h>头文件中。 1 struct shmid_ds { 2 struct ipc_perm shm_perm; /* operation perms */ 3 int shm_segsz; /* size of segment (byte... 阅读全文
posted @ 2013-01-20 11:07 Rabbit_Dale 阅读(3535) 评论(0) 推荐(0) 编辑
摘要:1、概述 Posix提供了两种在无亲缘关系进程间共享内存区的方法:(1)内存映射文件:先有open函数打开,然后调用mmap函数把得到的描述符映射到当前进程地址空间中的一个文件(上一篇笔记所用到的就是)。(2)共享内存区对象:先有shm_open打开一个Posix IPC名字(也可以是文件系统中的一个路径名),然后调用mmap将返回的描述符映射到当前进程的地址空间。者两种方法多需要调用mmap,差别在于作为mmap的参数之一的描述符的获取手段。2、Posix共享内存区对象 Posix共享内存区涉及以下两个步骤要求:(1)指定一个名字参数调用shm_open,以创建一个新的共享内存区对象或打开. 阅读全文
posted @ 2013-01-19 15:59 Rabbit_Dale 阅读(3647) 评论(0) 推荐(0) 编辑
摘要:共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。 采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量... 阅读全文
posted @ 2013-01-16 15:08 Rabbit_Dale 阅读(3485) 评论(2) 推荐(0) 编辑
摘要:System V 信号量在内核中维护,其中包括二值信号量 、计数信号量、计数信号量集。二值信号量 : 其值只有0、1 两种选择,0表示资源被锁,1表示资源可用;计数信号量:其值在0 和某个限定值之间,不限定资源数只在0 1 之间;计数信号量集 :多个信号量的集合组成信号量集内核维护的信号量集结构信息如下:定义在头文件<sys/sem.h>struct semid_ds { struct ipc_perm sem_perm; struct sem *sem_base; ushort sem_nsems;... 阅读全文
posted @ 2013-01-14 10:55 Rabbit_Dale 阅读(4629) 评论(0) 推荐(1) 编辑
摘要:1、概述 信号量(semaphore)是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语。信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。信号量的值为正的时候,说明它空闲。所测试的线程可以锁定而使用它。若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒。Posix信号量分为有名信号量和无名信号量(也叫基于内存的信号量)。2、Posix有名信号量 有名信号量既可以用于线程间的同步也可以用于进程间的同步。1)由sem_open来创建一个新的信号量或打开一个已存在的信号量。其格式为:sem_t *sem_open(const char *.. 阅读全文
posted @ 2013-01-13 19:39 Rabbit_Dale 阅读(4789) 评论(0) 推荐(3) 编辑
摘要:1、概述 记录锁是读写锁的一种扩展类型,可用于亲缘关系或无亲缘关系的进程之间共享某个文件的读与写。被锁住的文件通过文件描述符进行访问,执行上锁的操作函数是fcntl,这种类型的锁通常在内核中维护。 记录锁的功能是:一个进程正在读或修改文件的某个部分时,可以阻止其他进程修改同一文件区,即其锁定的是文件的一个区域或整个文件。记录锁有两种类型:共享读锁,独占写锁。基本规则是:多个进程在一个给定的字节上可以有一把共享的读锁,但在一个给定字节上的写锁只能有一个进程独用。即:如果在一个给定的字节上已经有一把读或多把读锁,则不能在该字节上再加写锁;如果在一个字节上已经有一把独占性的写锁,则不能再对它加任.. 阅读全文
posted @ 2013-01-11 12:02 Rabbit_Dale 阅读(2696) 评论(0) 推荐(1) 编辑
摘要:1、概述 读写锁与互斥量类似,不过读写锁允许更高的并行性。互斥量要么是锁住状态,要么是不加锁状态,而且一次只有一个线程对其加锁。读写锁可以有三种状态:读模式下加锁状态,写模式下加锁状态,不加锁状态。一次只有一个线程可以占有写模式的读写锁,但是多个线程可用同时占有读模式的读写锁。读写锁也叫做共享-独占锁,当读写锁以读模式锁住时,它是以共享模式锁住的,当它以写模式锁住时,它是以独占模式锁住的。2、读写锁API 读写锁的数据类型为pthread_rwlock_t。如果这个类型的某个变量是静态分配的,那么可通过给它赋常值PTHREAD_RWLOCK_INITIALIZER来初始化它。获取和释放读... 阅读全文
posted @ 2013-01-09 16:17 Rabbit_Dale 阅读(4702) 评论(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 阅读(10772) 评论(3) 推荐(4) 编辑
摘要:转载自:http://bbs.chinaunix.net/viewthread.php?tid=265266作者:beginner-bj请问管道和消息队列有什么不同管道通信(PIPE)管道通信方式的中间介质是文件,通常称这种文件为管道文件。两个进程利用管道文件进行通信时,一个进程为写进程,另一个进程为读进程。写进程通过写端(发送端)往管道文件中写入信息;读进程通过读端(接收端)从管道文件中读取信息。两个进程协调不断地进行写、读,便会构成双方通过管道传递信息的流水线。利用系统调用PIPE()创建一个无名管道文件,通常称为无名管道或PIPE;利用系统调用MKNOD()创建一个有名管道文件,通常称为 阅读全文
posted @ 2013-01-08 12:15 Rabbit_Dale 阅读(7672) 评论(0) 推荐(1) 编辑
摘要:消息队列中的消息结构可以由我们自由定义,具备较强的灵活性。通过消息结构可以共享一个队列,进行消息复用。通常定义一个类似如下的消息结构:#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 阅读(1466) 评论(1) 推荐(1) 编辑
摘要:1、概述 消息队列可以认为是一个消息链表,System V 消息队列使用消息队列标识符标识。具有足够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息。在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达。SystemV 消息队列是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。可以将内核中的某个特定的消息队列画为一个消息链表,如下图所示:对于系统中没个消息队列,内核维护一个msqid_ds的信息结构:struct msqid_ds{ struct msqid_ds { struct . 阅读全文
posted @ 2013-01-07 11:03 Rabbit_Dale 阅读(2985) 评论(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 阅读(4068) 评论(0) 推荐(0) 编辑
摘要:消息队列可以认为是一个消息链表,某个进程往一个消息队列中写入消息之前,不需要另外某个进程在该队列上等待消息的达到,这一点与管道和FIFO相反。Posix消息队列与System V消息队列的区别如下:1. 对Posix消息队列的读总是返回最高优先级的最早消息,对System V消息队列的读则可以返回任意指定优先级的消息。2. 当往一个空队列放置一个消息时,Posix消息队列允许产生一个信号或启动一个线程,System V消息队列则不提供类似的机制。Posix消息队列操作函数如下:#include <mqueue.h>typedef int mqd_t;mqd_t mq_open(co 阅读全文
posted @ 2013-01-04 11:06 Rabbit_Dale 阅读(7494) 评论(0) 推荐(1) 编辑
摘要:管道(pipe) 管道在Unix及Linux进程间通信是最基础的,很容易理解。管道就像一个自来水管,一端注入水,一端放出水,水只能在一个方向上流动,而不能双向流动。管道是典型的单向通信,即计算机网络中所说的“半双工”。管道又名匿名管道,所以只能用在具有公共祖先的进程之间使用,通常使用在父子进程之间通信。通常是父进程创建一个管道,然后fork一个子进程,此后父子进程共享这个管道进行通信。 管道由pipe函数创建,函数原型如下: #include<unistd.h> int pipe(int fd[2]); 成功返回0,否则返回-1;参数fd返回两个文件描述符,fd[0]为读,fd[1 阅读全文
posted @ 2012-12-09 16:03 Rabbit_Dale 阅读(3655) 评论(3) 推荐(0) 编辑