08 2009 档案
摘要:关于<Beginning Linux Programming 3ed>近两年来在我的博客里陆续发的一些关于Linux编程的文章是译自Wrox公司的<Beginning Linux Programming 3ed>一书,在此感谢朋友们的支持。另外需要说明的一点就是,记得07年的冬天我在长沙逛书店的时候似乎看到了这本书的中文译本,所以提醒朋友们,如果觉得这本书对自己有用,可以到书店买中文译本来看,想来中文译本会比我的翻译更为专业。算起来尝试翻译这本书似乎已经有两年多的时间了。记得当时还是在学校里面,一次浏览linux.org时,见到旁边的广告里推荐这本书,于是就是网上搜索到并下载下来,
阅读全文
摘要:CD数据库程序现在我们可以使用我们在这一章所了解的IPC工具来修改我们的CD数据库程序。我们可以使用三种IPC工具的多种不同组,但是因为我们需要传送的信息很少,直接使用消息队列实现请求的传递是一个很明显的选择。如果我们需要传递的数据量很大,我们可以考虑使用共享内存传递实际的数据,并且使用信号量或是消息来传递一个标记通知其他的进程在共享内存中有数据可用。消息队列接口解决我们了在第11章所遇到的问题,即当数据传递时我们需要两个进程使得管道打开。使用消息队列可以使得一个进程将消息放入队列,尽管这个进程是当前队列的唯一用户。我们需要考虑的一个重要决定就是将答案返回给客户。一个简单的选择就是使得一个队列
阅读全文
摘要:消息队列现在我们来讨论第三种也是最后一种System V IPV工具:消息队列。在许多方面看来,消息队列类似于有名管道,但是却没有与打开与关闭管道的复杂关联。然而,使用消息队列并没有解决我们使用有名管道所遇到的问题,例如管道上的阻塞。消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法。与有名管道比较起来,消息队列的优点在独立于发送与接收进程,这减少了在打开与关闭有名管道之间同步的困难。消息队列提供了一种由一个进程向另一个进程发送块数据的方法。另外,每一个数据块被看作有一个类型,而接收进程可以独立接收具有不同类型的数据块。消息队列的好处在于我们几乎可以完全避免同步问题,并且可以通过
阅读全文
摘要:共享内存共享内存是第二种IPC工具。他允许两个无关的进程访问相同的逻辑内存。共享内存是在两个运行的程序之间传递数据的有效手段。尽管X/Open标准并没有要求,很可能绝大数的共享内存实现都是会将不同进程之间正在共享的内存安排在相同的物理内存中。共享内存为在多个进程之间共享与传递数据提供一个有效的手段。因为他并没有提供同步的方法,所以通常我们需要使用其他的机制来同步对共享内存的访问。通常,我们也许会使用共享内存来提供对大块内存区的有效访问,并且传递少量的消息来同步对此内存的访问。共享内存是由IPC为一个进程所创建并且出现在这个进程的地址空间中的一段特殊的地址序列。其他的进程可以将同样的共享内存段关
阅读全文
摘要:第14章 信号量,共享内存与消息队列在这一章,我们将会讨论Unix发行版AT&T系统V.2所引入的进程通信工具集合。因为这些程序出现在相关的发行版本中并且具有类似的编程接口,他们通常被称之为IPC程序,或是更为通常的System V IPC。正如我们已经了解到的,他们绝不是进程之间通信的唯一方法,但是System V IPC通常用来指这些特殊的程序。在这一章,我们将会讨论下列内容:用于管理资源访问的信号量用于程序之间高效共享数据的共享内存用于在程序之间简单传递数据的消息队列信号量当我们在多用户系统,多进程系统,或是两者混合的系统中使用线程操作编写程序时,我们经常会发现我们有段临界代码,
阅读全文
摘要:Linux Kernel 2.6.30的发布已是很早之前的事情了,而且在其发布后不久就为了尝鲜在自己的机子上编译了2.6.30的内核,无奈fglrx 9.6与9.7都不对其进行支持,无法在新版本的内核下编译安装fglrx驱动,没有办法一直在2.6.29的内核下配合fglrx 9.5进行使用,因而在每次更新时都会期盼fglrx的更新,然而其更新版本都不能进行成功的编译,实是无奈啊!!昨天进行了系统更新,发现fglrx也进行更新,在更新安装完成后第一件事就是尝试编译新版本的fglrx驱动,令人高兴的编译终于成功了,并且在更新相应的文件后成功安装fglrx 9.8,并且在起动后,以前在起动X之前的f
阅读全文
摘要:管道下面是管道实现文件,pipe_imp.c,其中有客户端与服务器端函数。试验--管道实现头文件1 首先是#include:#include "cd_data.h"#include "cliserv.h"2 我们定义一些在此文件的其他函数中所需要的值:static int server_fd = -1;static pid_t mypid = 0;static char client_pipe_name[PATH_MAX + 1] = {‘/0’};static int client_fd = -1;static int client_write_fd
阅读全文
摘要:搜索数据库在CD关键字上的搜索比较复杂。函数的用户希望一旦调用就启动一个搜索。我们在第7章通过将在第一次调用上的*first_call_ptr设置为true并且函数返回第一个匹配结果来满足这种需求。在接下来的搜索函数调用中,*first_call_ptr设置为false,从而会返回更多的匹配,每次调用返回一个匹配结果。现在我们已经将程序分为两个进程,我们不能再允许搜索在服务器端一次处理一个实体,因为另一个不同的客户端也许会由服务器请求一个不同的搜索,而我们的搜索仍在处理之中。我们不能使得服务器端为每一个客户端单独存储搜索内容(搜索已经进行到哪里),因为当一个用户找到他们要找的CD关键值时或是客
阅读全文
摘要:CD数据库程序现在我们已经了解了我们可以如何使用有名管道来实现一个简单的客户端/服务器系统,我们可以重新查看我们的CD数据库程序并且进行相应的修改。我们同时组合了一些信号处理从而允许我们在进程被中断时进行一些清理动作。我们会使用我们前面的具有一个命令行接口的dbm版本,从而进可能直接的查看代码。在我们更为详细的讨论新版本的代码之前,让我们先编译这个程序。如果我们有由Web站点所获得的源代码,就可以使用makefile来编译生成server与client程序。输入server -i使得程序初始化一个新的CD数据库。无需多言,客户端直到服务器启动并运行时才运行。下面是makefile文件,显示程序
阅读全文
摘要:读取与写入FIFO使用O_NONBLOCK模式会影响作用在FIFO上的read与write调用的行为。在一个空的阻塞FIFO(例如,没有使用O_NONBLOCK打开的)上的read调用将会等待直到有数据可以读取。相反,在非阻塞且没有数据的FIFO上进行read调用将会返回0字节。在一个完全阻塞的FIFO上的write调用将会等待直到数据可以写入。在一个不能全部接受所有将要写入数据的FIFO上的write调用将会:如果请求PIPE_BUF字节或是小于且数据不能写入时将会失败。如果请求大于PIPE_BUF字节将会写入部分数据,返回实际写入的字节数据,其值为0。FIFO的大小是一个重要的考虑因素。在
阅读全文
摘要:有名管道:FIFO到目前为止,我们只是可以在两个相关的程序之间传递数据,也就是说,由一个共同的祖先进程启动的程序。通常这并不是十分方便,因为我们希望不相关的进程也可以交换数据。我们可以使用FIFO来实现这个操作,通常称之为有名管道。一个有名管道是在文件系统中作为名字存在的一个特殊的文件类型(记住,在Linux一切皆文件),但是行为类似于我们已经了解的无名管道。我们可以通过命令行或是在一个程序内部创建有名管道。由于历史原因,用于创建有名管道的命令为mknod:$ mknod filename p然而,mknod命令并不在X/Open命令列表中,所以他并不是在所有的类Unix系统上都可用。更好的命
阅读全文
摘要:父子进程我们的pipe调用探索的下一步就是使得子进程是与父进程不同的一个程序,而不是运行相同程序的另一个进程。我们可以使用exec调用来完成这个任务。这样做的一个困难就是通过exec执行的新进程需要知道访问哪一个文件描述符。在exec调用之后,就不再是这样的情况了,因为老进程已经被新的子进程所替代。我们可以通过向exec所执行的新进程传递文件描述符作为参数就可以解决这个问题。要显示这是如何工作的,我们需要两个程序。第一个就是数据生产者,他创建管道并且调用子进程,数据消费者。试验--管道与exec1 作为第一个程序,我们将pipe2.c修改为pipe3.c。对比这两个文件我们可以看到修改的行:#
阅读全文
摘要:管道调用我们已经了解了高层的popen函数,现在我们继续来了解低层的pipe函数。这个函数提供了一个在两个函数之间传递数据的方法,而不必调用shell来解释所请求的命令的。同时他也为我们提供了更多的数据读写控制。pipe函数的原型如下:#include <unistd.h>int pipe(int file_descriptor[2]);pipe函数接受一个两个整数文件描述符的数组作为参数。他会使用两个新的文件描述符来填充这个数据并且返回一个零值。如果失败则会返回-1并且设置errno来指明失败原因。Linux手册页中所定义的错误如下:EMFILE:进程正在使用的文件描述符过多EN
阅读全文
摘要:传递更多的数据到目前为止我们所用的机制只是简单的在一个fread或是fwrite中发送或是接收全部的数据。有时我们也许以更小的尺寸发送数据,或是也许我们并不知道输出的大小。为了避免声明一个大的缓冲区,我们可以使用多个fread或是fwrite调用并分别处理这些数据。下面是一个程序,popen3.c,由一个管道中读取所有的数据。试验--由一个管道读取大量的数据在这个程序中,我们由一个被调用的ps -alx进程读取数据。并没有办法预先知道会有多少输出,所以我们必须由管道中多次读取。#include <stdio.h>#include <stdlib.h>#include &
阅读全文