在看 apue 第 21 章 与网络打印机通信一章时,发现一段关于链表操作的代码有问题,现在摘出来让大家 review 一下。先上代码:

printd.c

这是打印服务的源代码,在打印时,用户通过  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] 书中关于打印服务代码的一个错误的更多相关文章

  1. 关于Java中的继承和组合的一个错误使用的例子

    [TOC] 关于Java中的继承和组合的一个错误使用的例子 相信绝大多数人都比较熟悉Java中的「继承」和「组合」这两个东西,本篇文章就主要就这两个话题谈论一下.如果我某些地方写的不对,或者比较幼稚, ...

  2. 路由器安装ubuntu-16.04.1-server-amd64出现“无法安装busybox-initramfs”错误。向目标系统中安装busybox-initramfs软件包时出现一个错误。请检查/var/log/syslog或查看第四虚拟控制台以获得详细

    公司的路由器要ubuntu服务器进行路由网络功能的管理,在安装的时候出现下面的错误提示: 安装ubuntu-16.04.1-server-amd64出现“无法安装busybox-initramfs”错 ...

  3. APUE 书中 toll 函数

    今天看unix环境高级编程时,随着书上的源码打了一遍,编译时提示 toll函数未定义, 找了半天(恕我对上下文不了解).看了英文版和源代码文件才知道, 中文版打印错了: toll => atol ...

  4. C# sliverlight调用WCF服务出现的一个错误

    错误提示如下: 尝试向 URI“http://localhost:8396/Service1.svc”发出请求时出错.这可能是由于试图以跨域方式访问服务而又没有正确的跨域策略,或策略不适用于 SOAP ...

  5. [apue] 书中关于伪终端的一个纰漏

    在看 apue 第 19 章伪终端第 6 节使用 pty 程序时,发现“检查长时间运行程序的输出”这一部分内容的实际运行结果,与书上所说有出入. 于是展开一番研究,最终发现是书上讲的有问题,现在摘出来 ...

  6. unix编程书中的 ourhdr.h代码

    真心不知到里面写的具体什么意思,先记下吧. /*Our own header, to be included after all standard system headers*/ #ifndef _ ...

  7. IIS8中部署WCF服务出错:HTTP 错误 404.3 - Not Found

    解决方法,以管理员身份进入命令行模式,运行: "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ ...

  8. 解决android调用IIS Express中的WCF服务时,出现错误400问题

    IIS Express仅支持localhost主机名地址访问. 找到IIS Express Config文件下的 applicationhost.confi   修改配置 再来调试android应用, ...

  9. 在commons-lang3包中StringUtils类的ordinalIndexOf中有一个错误

    * StringUtils.ordinalIndexOf(null, *, *) = -1 * StringUtils.ordinalIndexOf(*, null, *) = -1 * String ...

  10. 如何自己编译apue.3e中代码 & 学习写makefile

    本来是搜pthread的相关资料,看blog发现很多linux程序员都看的一本神书<APUE>,里面有系统的两章内容专门讲pthread(不过是用c语言做的代码示例,这个不碍事,还是归到原 ...

随机推荐

  1. spring boot整合spring cloud

    本项目还是通过卖票和买票模块来介绍spring cloud. 1.新建服务注册模块:eureka-server 1.1 配置pom <?xml version="1.0" e ...

  2. 《系列二》-- 7、后置处理器-PostProcessor

    目录 什么是后置处理器 spring 源码中已知的,顶级PostProcessor 其它 "后置处理器" 阅读之前要注意的东西:本文就是主打流水账式的源码阅读,主导的是一个参考,主 ...

  3. Redis分布式锁的正确使用姿势

    前言 分布式锁在日常开发中,用处非常的多.包括但不限于抢红包,秒杀,支付下单,幂等,等等场景. 分布式锁的实现方式有多种,包括redis实现,mysql实现,zookeeper实现等等.而其中redi ...

  4. C++字符串大写字母转小写字母

    #include <iostream> #include <stdio.h> using namespace std; char* Capital_to_Small(char* ...

  5. win32-制作mini dump文件

    一个完整的用户模式dump是基本的用户模式转储文件. 此转储文件包括进程的整个内存空间,程序的可执行映像本身,句柄表以及其他信息,这些信息对于调试器在重建转储发生时正在使用的内存中很有用. 可以将完整 ...

  6. RN运行ios报错No matching function for call to 'RCTBridgeModuleNameForClass'

    xcode更新12.5后,ios运行报错No matching function for call to 'RCTBridgeModuleNameForClass' 解决方法: 在ios/Podfil ...

  7. WSL2镜像文件压缩

    WSL2的镜像文件(*.vhdx)支持自动扩容,但是一般不会自动缩容.一旦某次存放过大文件以后,即使后续删除,镜像文件体积仍然不会缩小,导致大量磁盘空间浪费.因此,可以定期对镜像文件进行手动压缩. 镜 ...

  8. python Apscheduler持久化

    from pytz import utc from apscheduler.schedulers.background import BackgroundScheduler from apschedu ...

  9. vscode+gitee+picgo实现稳定图床

    目录: 目录 目录: 1. 为什么使用vscode+gitee+picgo实现完美图床 2. 安装VSCode 2.1 安装VSCode软件及相关插件 3. 安装picgo 4. 准备Gitee图床 ...

  10. kotlin协程小记

    转载请标明出处:https://www.cnblogs.com/tangZH/p/16849169.html -[kotlin协程小记]-[协程的async使用]- [kotlin协程异常处理之-tr ...