[apue] 书中关于打印服务代码的一个错误
在看 apue 第 21 章 与网络打印机通信一章时,发现一段关于链表操作的代码有问题,现在摘出来让大家 review 一下。先上代码:
这是打印服务的源代码,在打印时,用户通过 print 命令提交待打印的文件,print 命令通过 tcp 与 printd 服务通讯,
将文件及打印相关的参数传递给后者;对于每个客户,printd 服务会创建一个 worker 结构节点,
放在一个由 workers 变量指定了头的双向链表中。所以这段代码本质上就是简单的双向链接操作:
1 void add_worker (pthread_t tid, int sockfd)
2 {
3 struct worker_thread *wtp;
4 if ((wtp = malloc (sizeof (struct worker_thread))) == NULL) {
5 log_ret ("add_worker: can't malloc");
6 pthread_exit ((void *)1);
7 }
8
9 wtp->tid = tid;
10 wtp->sockfd = sockfd;
11
12 log_msg ("prepare to add worker");
13 pthread_mutex_lock (&workerlock);
14
15 wtp->prev = NULL;
16 wtp->next = workers;
17 if (workers == NULL)
18 workers = wtp;
19 else
20 workers->prev = wtp;
21
22 pthread_mutex_unlock (&workerlock);
23 }
重点就是 15-20 这 6 行啦(原文p633,代码499-504行),当第一次加入节点时, workers 为 NULL,所以走第一个条件分支,这没有问题;
但是再加入节点时, workers 不为 NULL,此时走 else 分支,将当前头的上一个节点设置为待插入的新节点 wtp,
到现在还好,可是等等,怎么就没下文了?!这个节点还没完全加入链表呢……
正确的做法应该是在结尾前再加一句:
else
{
workers->prev = wtp;
workers = wtp;
}
这样才能算完嘛。道理就不多说了,不信自己画个链表看看。下面给出优化后的完整代码:
1 void add_worker (pthread_t tid, int sockfd)
2 {
3 struct worker_thread *wtp;
4 if ((wtp = malloc (sizeof (struct worker_thread))) == NULL) {
5 log_ret ("add_worker: can't malloc");
6 pthread_exit ((void *)1);
7 }
8
9 wtp->tid = tid;
10 wtp->sockfd = sockfd;
11 pthread_mutex_lock (&workerlock);
12
13 wtp->prev = NULL;
14 wtp->next = workers;
15 if (workers != NULL)
16 workers->prev = wtp;
17
18 workers = wtp;
19
20 pthread_mutex_unlock (&workerlock);
21 }
好吧,我承认作为经典著作也会有这种低级错误。
今天的吹毛求疵就到这里,作为一个有职业素养的程序员,不在鸡蛋里挑出骨头来不罢休,嘿嘿……
[apue] 书中关于打印服务代码的一个错误的更多相关文章
- 关于Java中的继承和组合的一个错误使用的例子
[TOC] 关于Java中的继承和组合的一个错误使用的例子 相信绝大多数人都比较熟悉Java中的「继承」和「组合」这两个东西,本篇文章就主要就这两个话题谈论一下.如果我某些地方写的不对,或者比较幼稚, ...
- 路由器安装ubuntu-16.04.1-server-amd64出现“无法安装busybox-initramfs”错误。向目标系统中安装busybox-initramfs软件包时出现一个错误。请检查/var/log/syslog或查看第四虚拟控制台以获得详细
公司的路由器要ubuntu服务器进行路由网络功能的管理,在安装的时候出现下面的错误提示: 安装ubuntu-16.04.1-server-amd64出现“无法安装busybox-initramfs”错 ...
- APUE 书中 toll 函数
今天看unix环境高级编程时,随着书上的源码打了一遍,编译时提示 toll函数未定义, 找了半天(恕我对上下文不了解).看了英文版和源代码文件才知道, 中文版打印错了: toll => atol ...
- C# sliverlight调用WCF服务出现的一个错误
错误提示如下: 尝试向 URI“http://localhost:8396/Service1.svc”发出请求时出错.这可能是由于试图以跨域方式访问服务而又没有正确的跨域策略,或策略不适用于 SOAP ...
- [apue] 书中关于伪终端的一个纰漏
在看 apue 第 19 章伪终端第 6 节使用 pty 程序时,发现“检查长时间运行程序的输出”这一部分内容的实际运行结果,与书上所说有出入. 于是展开一番研究,最终发现是书上讲的有问题,现在摘出来 ...
- unix编程书中的 ourhdr.h代码
真心不知到里面写的具体什么意思,先记下吧. /*Our own header, to be included after all standard system headers*/ #ifndef _ ...
- IIS8中部署WCF服务出错:HTTP 错误 404.3 - Not Found
解决方法,以管理员身份进入命令行模式,运行: "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ ...
- 解决android调用IIS Express中的WCF服务时,出现错误400问题
IIS Express仅支持localhost主机名地址访问. 找到IIS Express Config文件下的 applicationhost.confi 修改配置 再来调试android应用, ...
- 在commons-lang3包中StringUtils类的ordinalIndexOf中有一个错误
* StringUtils.ordinalIndexOf(null, *, *) = -1 * StringUtils.ordinalIndexOf(*, null, *) = -1 * String ...
- 如何自己编译apue.3e中代码 & 学习写makefile
本来是搜pthread的相关资料,看blog发现很多linux程序员都看的一本神书<APUE>,里面有系统的两章内容专门讲pthread(不过是用c语言做的代码示例,这个不碍事,还是归到原 ...
随机推荐
- 关于php redis的geocoding函数
在php的redis扩展官方github上,文档的最下面的确存在geocoding的函数说明.但是笔者尝试调用geoAdd函数时,返回值一直为false.就纳闷了,是使用的姿势不对,还是存在其它问题? ...
- java处理json类型数据--阿里巴巴fastjson api常用方法实战
fastjson介绍 最近工作上经常需要解析json类型数据以及java对象到json类型的互转,特地研究了下阿里巴巴的fastjson,这个是国内用的 比较多的json转换api,还有其他的入jac ...
- pycharm—flask创建简单web项目
1.系统 系统 版本 OS win 10 pycharm 专业版2022.3.1 2.引入flask包 pip install flask 3.项目目录展示.代码.浏览器访问 from flask i ...
- 全栈式测试平台RunnerGo核心功能模块-接口管理
全栈式测试平台RunnerGo相对于市面上其他性能测试产品来说更简单,它不用其他相关配件,天然支持分布式,有单独的机器做分布式的负载均衡,自有一套智能算法算压力机的配置从而平均分配,并从场景链路的流 ...
- 【Azure 应用服务】在App Service中新建WebJob时候遇见错误,不能成功创建新的工作任务
问题描述 在Azure App Service界面上,添加新的Web Job(工作任务)时,一直添加失败.无详细错误提示,在App Service的Activity Logs(活动日志)中,根本没有添 ...
- STM32SPIFLASH读写
STM32SPIFLASH读写 1.1 SPI注意事项 SPI是同步通信,即通信双方每次信息交互必会带有一问一答,这代表在正常的单核MCU(例如STM32)中很难实现软件模拟的双向SPI通信(TFT屏 ...
- 『Echarts』基本使用
一.前言 本篇文章是『Echarts』文章的第 2 篇,主要介绍『Echarts』基本使用 在『Echarts』第 1 篇文章中,我们介绍了 Echarts 的概述及其强大的数据可视化功能.本篇将继续 ...
- AIGC下一步:如何用AI再度重构或优化媒体处理?
让媒资中"沉默的大多数"再次焕发光彩. 邹娟|演讲者 编者按 AIGC时代下,媒体内容生产领域随着AI的出现也涌现出更多的变化与挑战.面对AI的巨大冲击,如何优化或重构媒体内容生产 ...
- MAUI调用.so库
必要条件: (一)安装JDK (二)安装NDK (三)安装Android Studio(其实可以不用装也行) 使用Android Studio构件.so包 构件.so包 1. 使用Android st ...
- 十五: InnoDB的存储结构
InnoDB的存储结构 1.数据库的存储结构:页 索引结构给我们提供了高效的索引方式,不过索引|信息以及数据记录都是保存在文件上的,确切说是存储在页结构中.另一方面,索引是在存储引擎中实现的,MySQ ...