Develop
文章平均质量分 73
mylxiaoyi
在探索中求知,在思考中前进
展开
-
POSIX线程(三)
并发执行下面我们将要编写一个检测两个线程是否并发执行的程序。因为我们还没有了解要有效完成这一任务所需要的线程同步的知识,所以这并不是一个高效完成在线程之间称之为池操作的程序。再一起说明,我们要利用这一事实,在一个进程内部的不同线程之间共享除了局部函数变量之外的所有变量。试验--两个线程的同步执行在这一部分,我们所创建的程序thread2.c,是对thread1.c进行了翻译 2009-07-08 18:21:00 · 1743 阅读 · 0 评论 -
进程间通信(三)
管道调用我们已经了解了高层的popen函数,现在我们继续来了解低层的pipe函数。这个函数提供了一个在两个函数之间传递数据的方法,而不必调用shell来解释所请求的命令的。同时他也为我们提供了更多的数据读写控制。pipe函数的原型如下:#include int pipe(int file_descriptor[2]);pipe函数接受一个两个整数文件描述翻译 2009-08-02 09:04:00 · 834 阅读 · 0 评论 -
进程与信号(一)
第11章 进程与信号进程与信号构成了Linux操作环境的基础部分。他们控制了几乎所有由Linux与其他的类Unix计算机系统所执行的活动。理解Linux与Unix如何管理进程将会使得系统程序员,程序编写者,或是系统管理处于一个有利的位置。在这一章,我们将会了解在Linux环境中进程中如何被处理的以及如何确定在指定的时刻计算机正在做什么。我们同时也会了解如何在我们自己的程序中启动翻译 2009-05-24 18:02:00 · 1382 阅读 · 0 评论 -
进程间通信(二)
传递更多的数据到目前为止我们所用的机制只是简单的在一个fread或是fwrite中发送或是接收全部的数据。有时我们也许以更小的尺寸发送数据,或是也许我们并不知道输出的大小。为了避免声明一个大的缓冲区,我们可以使用多个fread或是fwrite调用并分别处理这些数据。下面是一个程序,popen3.c,由一个管道中读取所有的数据。试验--由一个管道读取大量的数据翻译 2009-08-01 13:00:00 · 1020 阅读 · 0 评论 -
POSIX线程-(五)
线程属性当我们第一次了解线程时,我们并没有讨论线程属性的问题。我们现在会进行讨论。线程有许多我们可以控制的属性。然而,在这里我们只讨论那些我们最需要的线程属性。其他属性的详细信息可以在手册中了解到。在所有我们前面的例子中,我们不得不在允许程序退出之前使用pthread_join来重新同步我们的线程。如里我们希望允许一个线程向创建他的线程返回数据时我们需要这样做。有时我们并不翻译 2009-07-21 18:02:00 · 1177 阅读 · 0 评论 -
调试(四)
了解更多有关gdb的内容GNU调试器是一个强大的工具,可以提供大量的有关运行程序内部状态的信息。在支持一个名叫硬件断点(hardware breakpoint)的实用程序的系统上,我们可以使用gdb来实时的查看变量的改变。硬件断点是某些CPU的一个特性;如果出现特定的条件,通常是在指定区域的内存访问,这些处理器能够自动停止。相对应的,gdb可以使用watch表达式。这就意味着,出于性能考虑,当一个翻译 2009-05-11 22:51:00 · 1328 阅读 · 1 评论 -
调试(三)
使用gdb调试我们将会使用GNU调试器,gdb,来调试这个程序。这是一个可以免费得到并且可以用于多个Unix平台的功能强大的调试器。他也是Linux系统上的默认调试器。gdb已经被移植到许多其他平台上,并且可以用于调试嵌入式实时系统。启动gdb让我们重新编译我们的程序用于调试并且启动gdb。$ cc -g -o debug3 debug3.c$ gdb debug3GNU gdb 5.2.1Cop翻译 2009-05-09 09:15:00 · 1127 阅读 · 0 评论 -
POSIX线程-(六)
线程属性-调度下面我们来看一下我们也许希望改变的第二个线程属性:调度。改变调度属性与设置分离属性相类似,但是我们可以使用另外两个函数来查找可用的等级级别,sched_get_priority_max与sched_get_priority_min。试验--调度因为thread6.c是与前面的例子十分类似,这里我们只看一下其中的区别。1 首先,我们需要一些额外的翻译 2009-07-23 18:24:00 · 2067 阅读 · 0 评论 -
POSIX线程-(四)
使用互斥同步在多线程程序中同步访问的另一个方法就是使用互斥,其作用允许程序锁住一个对象,从而只有一个线程可以访问他。要控制对临界区代码的访问,在我们进入这段代码之前锁住一个互斥量,并且在我们完成操作时进行解锁。使用互斥所需要基本函数与信号量所需要的函数相似,其声明如下:#include int pthread_mutex_init(pthread_mutex_t *翻译 2009-07-19 15:06:00 · 1340 阅读 · 0 评论 -
调试(二)
代码监视正如我们在前面所提到的,当程序并未按我们预期的那样运行时,重读我们的程序是一个好主意。出于本章的目的,我们假设代码已经进行重新检查,并且明显的错误已经进行了处理。我们可以使用一些工具来帮助我们进行代码检查,编译器就是明显的一个。如果在我们的程序中存在任何语法错误,编译器可以通知我们。我们在后面还会提到其他的工具,lint与Splint。与编译器类似,他们会分析代码并且报告不正确的代码。监视翻译 2009-04-26 11:12:00 · 1007 阅读 · 0 评论 -
调试(一)
第十章 调试所有的软件都会存在缺陷,通常每100行代码就会存在2到5个缺陷。这些错误通常会使得程序和库并不会预期的表现,通常会使得一个程序的行为并不会如预想的那样。Bug跟踪,标识以及修复会占用程序软件开发过程中的大量时间。在这一章,我们讨论软件缺陷,并且会考虑一些工具与技术用于跟踪特定的错误行为。这不同于测试(在各种条件下验证程序行为的任务),尽管测试与调试是相关联的,而且许多bug就是在测试过翻译 2009-04-23 23:44:00 · 1215 阅读 · 0 评论 -
开发工具(四)
发布软件程序发布的主要问题就是要保证包含所有的文件以及确切的版本。幸运的是,网络程序社区已经发展出一个健壮的方法集合可以很多的解决这个问题。这些方法包括:使用在所有的Unix机器上均可用的标准工具将所有的组件文件打包进入一个包文件中控制软件包的版本号包文件采用包含版本号的命名约定从而用户可以很容易分辨出他们正在处理的版本包中子目录的使用可以保证当文件由包文件中解压出来时,他们就会位于一个单独的目录翻译 2009-03-19 21:29:00 · 674 阅读 · 0 评论 -
开发工具(三)
内建规则到目前为止,我们已经在makefile文件中确切的指定了如何执行过程的每一步。事实上,makefile有大量的内建规则从而可以很大程度的简化makefile文件,特别是当我们有大量源文件的时候。下面我们创建foo.c,这是一个传统的Hello World程序。#include #include int main(){ printf(“Hello World/n”); exit(翻译 2009-03-14 16:20:00 · 1080 阅读 · 0 评论 -
开发工具(二)
Makefile中的注释makefile文件中的注释以#开始,并且直到本行结束。正如在C源文件中一样,makefile文件中的注释有助于作者也其他人更好的理解文件编写时所期望的作用。Makefile中的宏即使有make与makefile是管理多个源码文件工程的强大工具。然而,对于由大量的文件所组成的工程来说,他们仍显得庞大和不灵活。所以Makefile允许我们使用宏,从而我们可以将其写为更为通用的原创 2009-03-13 22:54:00 · 776 阅读 · 0 评论 -
数据管理(四)
锁区域创建锁文件对于资源的排他访问,例如串口,是相当合适的,但是对于访问大的共享文件就是太好了。假如我们拥有一个由一个程序写入的大文件,但是是由许多不同的程序进行持续更新的。当一个程序正在记录一些在较长的时间内所得到的数据,并且正在为其他的一些程序进行处理时就会出现这样的情况。这些正在处理的程序并不会等待日志程序结束--他们是连续运行的--所以他们需要一些合作的方法从而可以提供对于同一个文件的同时翻译 2008-12-27 23:02:00 · 690 阅读 · 0 评论 -
数据管理(二)
Null指针与MS-DOS不同,但是类似于新版本的Windows,现代的Linux系统会小心的处理读取或是写入由null指针所指向的地址,尽管实际的行为是实现相关的。试验--访问Null指针下面我们在memory5a.c程序中试一下当我们访问一个null指针时会发生什么情况:#include #include #include int main(){ char *some_memory =翻译 2008-12-20 12:15:00 · 610 阅读 · 0 评论 -
数据管理(三)
文件锁文件锁是多用户,多任务操作系统的重要一部分。程序经常需要共享数据,通常是通过文件,所以对于这些程序来说有一种可以建立文件控制的方法是十分重要的。这样文件就可以安全的进行更新,或者当一个程序在写入文件时,另一个程序会阻止自己试图由文件中读取。Linux有许多我们可以用于文件锁的特性。最简单的方法就是以原子方式创建文件锁的技术,从而当创建了这个锁以后可以阻止其他任何事情的发生。这样就赋予程序一种翻译 2008-12-21 10:37:00 · 558 阅读 · 0 评论 -
进程间通信(一)
第13章 进程间通信:管道在第11章,我们了解了使用信号在两个进程之间发送消息的一个简单方法。我们创建了可以用来引起响应的通知事件,但是所传递的信息限制于一个信号数量。在这一章,我们将会了解管道,这会允许在进程之间交换更为有用的数据。在本章的结尾,我们将会使用我们的新知识来重新将CD数据库程序实现为一个非常简单的客户/服务器程序。在本章,我们将会涉及下列主题:管翻译 2009-07-31 15:41:00 · 1441 阅读 · 2 评论 -
进程间通信(四)
父子进程我们的pipe调用探索的下一步就是使得子进程是与父进程不同的一个程序,而不是运行相同程序的另一个进程。我们可以使用exec调用来完成这个任务。这样做的一个困难就是通过exec执行的新进程需要知道访问哪一个文件描述符。在exec调用之后,就不再是这样的情况了,因为老进程已经被新的子进程所替代。我们可以通过向exec所执行的新进程传递文件描述符作为参数就可以解决这个问题。要翻译 2009-08-03 12:37:00 · 1018 阅读 · 0 评论 -
POSIX线程(二)
第一个线程程序有一个完整的与线程相关的库调用集合,其中的大多数名字以pthread_开头。要使用这些库调用,我们必须定义宏_REENTRANT,包含文件pthread.h,并且使用-lpthread来链接线程库。当设计原始的Unix与POSIX库函数时,假定在任何进程中只有一个执行线程。一个明显的例子就是errno,这个变量用于在调用失败之后获取错误信息。在一个多线程程序中翻译 2009-07-05 10:32:00 · 1624 阅读 · 0 评论 -
关于Beginning Linux Programming 3ed
关于近两年来在我的博客里陆续发的一些关于Linux编程的文章是译自Wrox公司的<Beginning Linux Programming 3ed>一书,在此感谢朋友们的支持。另外需要说明的一点就是,记得07年的冬天我在长沙逛书店的时候似乎看到了这本书的中文译本,所以提醒朋友们,如果觉得这本书对自己有用,可以到书店买中文译本来看,想来中文译本会比我的翻译更为专业。算起来尝试翻译这本书原创 2009-08-25 19:00:00 · 1471 阅读 · 1 评论 -
进程间通信应用-CD程序
CD数据库程序现在我们可以使用我们在这一章所了解的IPC工具来修改我们的CD数据库程序。我们可以使用三种IPC工具的多种不同组,但是因为我们需要传送的信息很少,直接使用消息队列实现请求的传递是一个很明显的选择。如果我们需要传递的数据量很大,我们可以考虑使用共享内存传递实际的数据,并且使用信号量或是消息来传递一个标记通知其他的进程在共享内存中有数据可用。消息队翻译 2009-08-25 18:06:00 · 1104 阅读 · 0 评论 -
POSIX线程(一)
第12章 POSIX线程在第11章,我们看到在Linux中进程是如何被处理的。这些多进程的特性很久以来就是类Unix操作系统的特性。有时使用fork创建一个新进程的代价实在是太大了。在这种情况下,使得一个程序同时做两件事情,或者至少看起来是如此是十分有用的。相对应的,我们也许希望以同样的方式同时发生两个或是更多的事情。这就是线程开始的地方。在这一章,我们将会了解:在一个翻译 2009-06-21 20:46:00 · 2766 阅读 · 0 评论 -
进程间通信之消息队列
消息队列现在我们来讨论第三种也是最后一种System V IPV工具:消息队列。在许多方面看来,消息队列类似于有名管道,但是却没有与打开与关闭管道的复杂关联。然而,使用消息队列并没有解决我们使用有名管道所遇到的问题,例如管道上的阻塞。消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法。与有名管道比较起来,消息队列的优点在独立于发送与接收进程,这减少了在打开与关翻译 2009-08-24 23:33:00 · 4305 阅读 · 2 评论 -
Linux进程间通信之信号量
第14章 信号量,共享内存与消息队列在这一章,我们将会讨论Unix发行版AT&T系统V.2所引入的进程通信工具集合。因为这些程序出现在相关的发行版本中并且具有类似的编程接口,他们通常被称之为IPC程序,或是更为通常的System V IPC。正如我们已经了解到的,他们绝不是进程之间通信的唯一方法,但是System V IPC通常用来指这些特殊的程序。在这一章,我们将会讨论下列内翻译 2009-08-22 08:43:00 · 7863 阅读 · 2 评论 -
进程与信号(五)
健壮的信号接口我们已经讨论了使用signal来发出与捕获信号,因为他们在较为旧的Unix程序中很常见。然而,X/Open与Unix规范推荐了一个更为健壮的用于信号处理的新的编程接口:sigaction。#include int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);翻译 2009-06-13 10:45:00 · 2171 阅读 · 1 评论 -
进程间通信(九)
管道下面是管道实现文件,pipe_imp.c,其中有客户端与服务器端函数。试验--管道实现头文件1 首先是#include:#include "cd_data.h"#include "cliserv.h"2 我们定义一些在此文件的其他函数中所需要的值:static int server_fd = -1;static pid_t myp翻译 2009-08-15 10:49:00 · 751 阅读 · 0 评论 -
进程与信号(四)
线程Linux进程可以协作,可以发送消息,也可以中断另一个进程。他们甚至可以在彼此之间共享内存段,但是在操作系统内部他们却是完全不同的实体。他们并不能共享变量。在许多Unix系统与Linux系统还有另一类名为线程的进程。线程在某些程序中具有巨大的价值,例如多线程数据库服务器,然而线程很难进行编程。Linux上的线程编程并不如使用多进程那样常见,因为Linux的进程是轻量级的翻译 2009-06-10 18:38:00 · 1824 阅读 · 1 评论 -
进程与信号(三)
等待一个进程当我们使用fork启动一个子进程时,他具有其自己的生命周期并且独立运行。有时,我们希望知道一个子进程何时结束。例如,在前一个例子中,父进程在子进程之前结束,从而我们得到混乱的输出,因为子进程还在继续运行。我们可以通过调用wait来使得父进程在继续运行之前等待,直到子进程结束。#include #include pid_t wait(int *stat_loc翻译 2009-06-08 18:49:00 · 1904 阅读 · 4 评论 -
进程与信号(二)
进程调度ps输出的一个特点就是ps命令实体本身:1357 pts/2 R 0:00 ps -ax这表明进程1357处于运行状态(R)并且正在执行命令ps -ax。所以进程是在其自身的输出中被描述的。状态指示器只是表明程序已经准备好运行,并不一定是在实际运行。在单处理器的计算机上,每次只能运行一个进程,而其他的进程必须依次等待。这些轮序,就是所谓的时间片,非常短,从而给我翻译 2009-06-07 12:21:00 · 1497 阅读 · 1 评论 -
进程间通信(八)
搜索数据库在CD关键字上的搜索比较复杂。函数的用户希望一旦调用就启动一个搜索。我们在第7章通过将在第一次调用上的*first_call_ptr设置为true并且函数返回第一个匹配结果来满足这种需求。在接下来的搜索函数调用中,*first_call_ptr设置为false,从而会返回更多的匹配,每次调用返回一个匹配结果。现在我们已经将程序分为两个进程,我们不能再允许搜索在服务器端翻译 2009-08-11 23:25:00 · 1206 阅读 · 2 评论 -
进程间通信(七)
CD数据库程序现在我们已经了解了我们可以如何使用有名管道来实现一个简单的客户端/服务器系统,我们可以重新查看我们的CD数据库程序并且进行相应的修改。我们同时组合了一些信号处理从而允许我们在进程被中断时进行一些清理动作。我们会使用我们前面的具有一个命令行接口的dbm版本,从而进可能直接的查看代码。在我们更为详细的讨论新版本的代码之前,让我们先编译这个程序。如果我们有由Web站点所翻译 2009-08-09 10:11:00 · 1442 阅读 · 0 评论 -
进程间通信(六)
读取与写入FIFO使用O_NONBLOCK模式会影响作用在FIFO上的read与write调用的行为。在一个空的阻塞FIFO(例如,没有使用O_NONBLOCK打开的)上的read调用将会等待直到有数据可以读取。相反,在非阻塞且没有数据的FIFO上进行read调用将会返回0字节。在一个完全阻塞的FIFO上的write调用将会等待直到数据可以写入。在一个不能全部接受所有将翻译 2009-08-08 10:08:00 · 887 阅读 · 0 评论 -
进程间通信(五)
有名管道:FIFO到目前为止,我们只是可以在两个相关的程序之间传递数据,也就是说,由一个共同的祖先进程启动的程序。通常这并不是十分方便,因为我们希望不相关的进程也可以交换数据。我们可以使用FIFO来实现这个操作,通常称之为有名管道。一个有名管道是在文件系统中作为名字存在的一个特殊的文件类型(记住,在Linux一切皆文件),但是行为类似于我们已经了解的无名管道。我们可以通翻译 2009-08-04 12:20:00 · 1994 阅读 · 4 评论 -
开发工具
在这一章,我们将会讨论在Linux系统上可用的程序开发工具,其中一些在Unix系统上也可用。除了必须的编译器与调试器以外,Linux提供了一个工具集,其中的每一个工具都完成单独的工作,并且允许开发者以新的方式对这些工具进行组合。这就是Linux所继承的Unix哲学的一部分。在这里,我们将会讨论其中的一些重要工具,并且会讨论使用这些工具解决问题的例子,包括:make命令以及makefile使用RCS翻译 2009-02-17 22:21:00 · 1063 阅读 · 1 评论 -
数据管理(一)
在前面的几章中,我们涉及到了资源限制的主题。在这一章,我们将会讨论管理我们资源分配的方法,然后讨论多个用户连续处理文件的方法,最后我们来讨论Linux系统所提供的工具如何处理将普通文件的限制用作一个数据存储介质的问题。我们可以数据管理总结为如下三个方面:动态内存管理:要做些什么而Linux不允许我们做什么文件锁:协作锁,共享文件锁区域,以及避免死锁dbm数据:一个基本的,大多数Linux系统中所提原创 2008-11-22 10:29:00 · 763 阅读 · 0 评论 -
Linux环境(五)--主机信息与日志
主机信息正如我们可以确定用户信息一样,程序也可以确定其运行的计算机的信息。uname命令提供了这些信息。uname同时也作为一个系统调用来在一个C程序中提供同样的信息,我们可以使用man 2 uname来查看详细的信息。许 多情况都需要主机信息。我们也许希望依据在网络中一个程序所运行的机器的名字来自定义其行为,也就是说,是一个学生的机器还是一个管理员的机器。为了授权 的目的,我们也许希望限制一个程翻译 2008-05-03 09:38:00 · 893 阅读 · 0 评论 -
Linux环境(四)--临时文件与用户信息
临时文件通常,程序需要以文件的形式使用临时存储。这也许是存储计算的中间结果,或者是在实际操作之前所做的文件拷贝备份。例如,一个数据程序在删除记录时会使用临时文件。文件会收集需要保存的数据库实体,然后在操作结束时,临时文件会成为新的数据库而原始的会被删除。临时文件的大量使用隐藏了他的一个缺点。我们必须小心来确保程序会选择一个唯一的名字来使用临时文件。如果不是这样,因为Linux是一个多任务系统,也许翻译 2008-04-27 10:56:00 · 1234 阅读 · 0 评论 -
Linux环境(二)--环境变量
环境变量我们在第2章讨论了环境变量。这些变量可以用来控制shell脚本和其他程序的形为。我们也可以使用他们来配置用户环境。例如,每一个用户都有一个环境变量,HOME,定义了其用户主目录,作为其会话的起始位置。正如我们所知的,我们由shell提示来测试环境变量:$ echo $HOME/home/neil我们也可以使用shell的set命令来列出所有的环境变量。Unix描述定义了许多标准的环境变量翻译 2008-04-19 15:15:00 · 2043 阅读 · 0 评论 -
Linux环境(三)--日期与时间
时间与日期通常对于一个程序来说可以确定时间与日期是十分用的。也许他要记录其运行的时间,或者是他要一个特定的时间改变其形为。例如,一个游戏程序也许不会在工作时间运行,或者是一个备份调度会在启动自动备份之前等待早些的工作完成。所有的Unix系统对于时间与日期都使用相同的起始点:1970年1月1日午午夜GMT。这是Unix的创世纪,而Linux也不例外。而在Linux系统中所有的时间都是以秒记量的。这与翻译 2008-04-22 11:10:00 · 1198 阅读 · 0 评论