线程一章通读

本篇和上篇一样,侧重了解作者的思路,设计方式,而不仅仅单纯的了解这些知识,当然,本次学习中,了解本章的知识也是一个目的之一,毕竟,对这一方面的内容还不算炉火纯青。

在本章的前导言中,对线程的概念作了较详细的解释,以及与进程的区别。我们在这里整理一下:
1.线程是允许一个程序执行不止一个的任务,而且看起来是并行运行。
2.进程运行时,至少创建一个线程。不同线程执行的是同一程序的不同部分。
3.子进程是从父进程那里复制虚拟内存,文件描述符,而线程是共享内存空间,文件描述符等。
4.一个进程中所有的线程都是执行统一程序,但是如果任何一个exec,所有其他线程就此中止。
5.用-lpthread保证连接
我个人认为:在原理上让初学者理解这么多,还是很有困难的。作者的构思上应该主要是与上一章对应。

下面本章的内容分成六节:1线程的创建,2线程的取消,3线程的专有数据,4同步和临界区,5GNU/Linux的线程实现,6进程和线程的比较。内容的安排上来看,重点或者常用的部分肯定在1和4节上。前面四节介绍具体的内容,后面两节转向总结。

第一节 线程的创建
前面的引子,后面分成a给线程传递数据,b等待线程,c线程的返回值,d线程id,e线程的属性
这样几个小节来介绍,我们逐细来看:
引子:
1.线程id来标志类型,c/c++中,为pthread_t
2.创建线程时,指定一个普通的函数,个人觉得这里,应该引入函数的声明,更方便说明。而且,这个函数的指针是否应该是对C语言学习者的一个很好的复习的例子。
3.作者在这里实际上详细的介绍了各个参数,和K&R的风格基本一致。
4.继续强调线程间的调度是异步调度,所以不能依赖于他们的先后关系。并引用实例说明。
个人觉得如果对操作系统的理解足够好的话,实验可简单安排,反之,可能从让学生来理解操作系统的一些原理。
5最后提到了线程的退出方式。这里可能可以重新开一个小的标题.

a向线程传递数据
原则上,我个人认为这里相对比较简单。可能基于以下两个原因
对C语言学生的复习,可能更多的学生还没有理解如何给一个函数指针传递参数的方式,其实在第五章系统接口的时候已经提到过。
第二个原因就是针对:实例引出问题,所以,承上启下。这和K&R的风格也算一致。

b线程的等待
用wait来对比于同样的操作,个人认为,也是应该先给出需要应用函数的生命在前面,这和K&R,Robbins的风格会一致。
然后重写上面的实例,给出本实例的教训或者目的。似乎这里应该强调一下主线程的概念。

c线程的返回值
这里给出一个例子,主线程要等待某个线程的返回值。这个可能有一些特别的应用,或许对多核的编程有借鉴意义。可能这里可以复习C语言的强制类型转换的概念。

d关于线程ID
一样,就是要添加这里用到的函数的声明。pthread_self,和pthread_equal
可以让学生实验一下线程等待自己结束是导致死锁还是返回错误代码。

e线程属性
继续保持原有的风格,对pthread_attr_t的数据结构或者是对pthread_attr_init,pthread_attr_destroy,pthread_attr_getdetachstate,pthread_detach的函数加以声明。

总结第一节来看,作者们表述的内容也应该相当齐整。我们只需要在格式上稍作变化即可。重点应该安排在实验上,让初学者有亲切体会。

第二节线程的取消,包含引子,a同步和异步线程,b不可取消的临界区,c何时使用线程取消
看引子,一样,我们需要先添加函数的声明。

线程是否可以取消取决于三种情况:
线程可以被一部取消
线程可以被同步取消
线程不可被取消
当一个线程刚被建立的时候,处在可被同步取消。

a同步和异步线程
同前面一样,要把pthread_setcanceltype等api先声明了。
可异步取消的线程可以在任意时刻取消,同步取消的线程只能在特殊位置取消,引入取消点的概念。并且还有直接取消点和间接取消点。这部分内容到现在也可能没有几个人了解。

b不可取消的临界区
一样介绍函数的声明,提出临界区这个大家都很熟悉的概念。以一个现实中最重要的例子银行系统说明。
c何时应该取消线程?
原则上取消线程不是一个很好的策略。

第三节线程专有数据
进程间线程的是共享数据空间的,但是每个线程还是有自己单独的调用栈。
如果要把线程中的一个变量的复制给每个线程,Linux给每个线程提供一个线程专有数据区。
c清理句柄
添加函数声明:pthread_cleanup_push,pthread_cleanup_pop
清理函数为了防止线程退出或者被取消的时候出现资源泄漏的问题。但有时需要创建清理函数但是却不希望有专有数据对象。清理句柄:当一个线程退出时被自动调用的函数。在线程被取消或者是中途退出时被调用。
C++清理方法。

第四节同步和临界代码段
首先从并行程序和异步调度来说明。调试中复现的困难。因为共享数据所以相互竞争的概念。
分a竞争状态,b互斥体,c互斥体死锁,d非阻塞互斥体测试,e线程信号量,f条件变量,g多个线程的死锁。这部分内容应该是这一章的重点。
a竞争条件,
这也是一个很好的说明并行性的例子。可以在操作系统原理中把这个例子引入。
这里也引入了原子操作的问题,不知道操作系统里会不会讲到。

b互斥体
函数的声明和数据结构的声明
这里,我认为应该指出:原子操作的不可行性。
其他的主要就是在引用实例。从写作的手段来看,基本上符合K&R的标准范式。

c互斥体死锁
一样的把本节用到的类型,函数进行声明。
三种互斥体:
快速,默认的mutex.
递归mutex:
纠错检测的mutex:
涉及到mutex的attribute问题。

d非阻塞互斥体测试
也就是trylock系列的函数。

e线程信号量
两种,一种是处理线程,一种是处理进程的。
觉得这里的例子也很好,一步步地深入地学习。而不是另起炉灶。

f条件变量
看来这一节我自己也还要好好的看看,都不记得怎么操作了,自己的阅读了这一节,大概弄清楚了,这里的例子还是很清楚的说明了这个问题。
我们还是要在每一节的头上把用到的函数,变量的类型加上。
这里的重点在于,如果已经设置,就不用等待,丢弃信号,如果没有设置,就等待,但是可以被信号唤醒。个人觉得这一节的论述比较啰嗦,不似作者风格。

g发生死锁
简单的介绍了死锁得发生情况,确切地说应该引入一个思想:
在共享资源的时候,很容易遇到死锁的情况,线程是共享进程内的资源,而操作系统确实多进程的又共享的硬件资源,所以,更容易出现死锁,所以花大量的篇幅再将并行性问题。

第五节:GNU/Linux的线程实现
这个实例揭示了linux系统上线程的实质---LWP。以及涉及内容:a信号处理,bclone的系统调用
a信号处理,进程间的信号有主线程处理,而线程之间也可以发信号。
bclone的系统调用,这里应该是说pthread是如何实现共享的,而不是拥有独立副本。

第六节就是讲进程和线程的区别
优势劣势,以及怎么样的选择。

通篇来说,浅显易懂是我们的准则。最后一节和开篇从不同的角度阐述进程与线程的不同
这里看起来,对线程的描述应该相当完整。我建议还是把我们的大纲完全按照这个顺序来执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值