在看 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. 使用DeskPins工具钉住窗口

    需求 我们经常一边看着PDF或视频教程,一边又打开一个文本编辑器/word/markdown编辑器在做一些笔记.问题是有时候呀需要来回切换(alt+tab)窗口,时间长了其实费时费力,这是一名工程师无 ...

  2. spring boot中使用定时任务

    1.在主类上添加EnableScheduling注解 package com.laoxu.gamedog; import org.springframework.boot.SpringApplicat ...

  3. Innodb存储引擎之锁

    目录 一.概述 二.lock 与 latch 三.Innodb存储引擎中的锁 锁 一致性非锁定读 一致性锁定读 自增长与锁 外键与锁 四.锁的算法 锁的算法 Phantom Problem 幻读问题 ...

  4. SpringBoot中Redis的基础使用

    基础使用 首先引入依赖 <!-- redis依赖--> <dependency> <groupId>org.springframework.boot</gro ...

  5. go值接收者和指针接收者的区别

    方法的接收者 package main import ( "fmt" ) type Person struct { Name string Age int } func (p Pe ...

  6. JVM类的加载和加载器

    JVM类的加载和类的加载器 一.类的加载过程 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来 ...

  7. 【C++ OOP 01】封装

    封装 封装的意义 封装是C++面向对象三大特性之一 封装的意义: 将属性和行为作为一个整体,表现生活中的事物 将属性和行为加以权限控制 封装意义一 ​ 在设计类的时候,属性和行为写在一起,表现事物 语 ...

  8. Vue3学习(二十)- 富文本插件wangeditor的使用

    写在前面 学习.写作.工作.生活,都跟心情有很大关系,甚至有时候我更喜欢一个人独处,戴上耳机coding的感觉. 明显现在的心情,比中午和上午好多了,心情超棒的,靠自己解决了两个问题: 新增的时候点击 ...

  9. ABP开发需要用到的命令

    0.命令行在哪里执行? 在Visual Studio的"解决方案资源管理器"的解决方案或者项目上点鼠标右键,选择"在终端中打开". 1.安装abp的命令行 官网 ...

  10. [Rust] 变量的属性: 不可变(immutable), 可变(mutable), 重定义(shadowing), 常量(const), 静态(static)

    [Rust] 变量的属性: 不可变(immutable), 可变(mutable), 重定义(shadowing), 常量(const), 静态(static) 变量的可变性 在 Rust 中, 变量 ...