《Linux/UNIX系统编程手册》 英文版读书笔记第29章

本文详细解析Linux下使用Pthreads API创建、管理线程的过程,包括pthread_create、pthread_exit、pthread_join等核心函数的用法及注意事项。讨论了线程ID的获取、线程间的join操作,以及线程终止的四种方式。同时,文章强调了线程与进程的区别,并解释了线程间join操作的限制和潜在问题。

errnois defined as amacro that expands into a function call returning a modifiable lvalue that is distinct for each thread. (Since
the lvalue is modifiable, it is still possible to write assignment statements of the formerrno = valuein threaded programs.)

On Linux, programs that use the Pthreads API must be compiled with thecc –pthread option. The effects of this option include the following: The_REENTRANTpreprocessor macro is defined. This causes the declarations of a few reentrant functions to be exposed.
z The program is linked with the libpthread library (the equivalent of–lpthread).


When a program is started, the resulting process consists of a single thread, called the initial or mainthread

#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
 void *(*start)(void *), void *arg);

The thread that callspthread_create()continues execution with the next statement that follows the call

Typically,argpoints to a global or heap variable, but it can also be specified asNULL

PTHREAD_CANCELED, the value returned when a thread is canceled (see Chapter 32), is usually some implementationdefined integer value cast tovoid *。
A portable application would need to ensure that normally terminating threads don’t return integer values that match PTHREAD_CANCELED on any of the implementations on which the application is to run

SUSv3 explicitly notes that the implementation need not initialize the buffepointed to bythreadbeforethe new thread starts executing; that is, the new thread may start running beforepthread_create()returns to its caller. 
If the new thread needs to obtain its own ID, then it must do so usingpthread_self()


线程的终止有四种方式
:
z The thread’s start function performs a return specifying a return value for the thread.
z The thread calls pthread_exit() (described below).
z The thread is canceled using pthread_cancel() (described in Section 32.1).
z Any of the threads calls exit(), or themain thread performs areturn(in the main()function), which causes all threads in the process to terminate immediately.

include <pthread.h>
void pthread_exit(void *retval);

pthread_exit()can be called from any function that has been called by the thread’sstart function.
pthread_exit specifies a return value that can be obtained in another thread by callingpthread_join
The value pointed to by retval should not be located on the thread’s stack, since the contents of that stack becomeundefinedon thread termination。 The same statement applies to the value given to areturnstatement in
the thread’s start function.



If the main thread callspthread_exit()instead of callingexit()or performing a return, then the other threadscontinue to execute

获取线程ID
include <pthread.h>
pthread_t pthread_self(void);

检测线程ID是否一样
include <pthread.h>
int pthread_equal(pthread_t t1, pthread_t t2);

SUSv3 also notes that an implementation is permitted to reusea thread ID after aterminatedthread has been joined withpthread_join()or after adetachedthread has terminated

POSIX thread IDs are assigned and maintained by the threading implementation
The thread ID returned bygettid()is a number (similar to a process ID) that is assigned by thekernel

pthread_join() 函数等待指定的线程thread终止,thread终止后pthread_join立即返回

include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
Returns 0 on success, or a positive error number on error

Calling pthread_join() for a thread ID that has been previously joined can lead to unpredictable behavior
重复对同一个thread调用两次pthread_join会造成无法预测的行为,
it might instead join with a thread created later that happened to reuse the same thread ID
可能join一个thread,是在之后创建的,只不过重用了之前的thread ID.

If a thread is not detached (see Section 29.7), then we must join with it using pthread_join(). If we fail to do this, then, when the thread terminates, it produces the thread equivalent of a zombie process
如果线程没有被detach,我们必用对它使用pthread_join,否则该线程终止后变为僵尸线程。

The task that pthread_join()performs for threads is similar to that performed bywaitpid()for processes. However, there are some notable differences
pthread_join和waitpid两个函数很相似,但是也有一些显著的不同。

Threads are peers. Any thread in a process can usepthread_join()to join with any other thread in the process. For example, if thread A creates thread B, which creates thread C, then it is possible for thread A to join with thread C, or vice versa. This differs from the hierarchical relationship between processes. When a parent process creates a child usingfork(), it is the only process that canwait()on that child. There is no such relationship between the thread that callspthread_create()and the resulting new thread.
线程是平等的,比如线程A创建了线程B,线程B创建了线程C,那么线程A可以join线程C,反之也可以。在进程中,只有父进程通过fork创建了子进程,只有这个父进程可以wait这个子进程。
z There is no way of saying “join with any thread” (for processes, we can do this using the callwaitpid(–1, &status, options)); nor is there a way to do a nonblocking join (analogous to thewaitpid()WNOHANGflag). There are ways to achieve similar functionality using condition variables;
线程不像进程,进程wait可以等待任意进程终止,线程也没有nonblocking 等待,不过线程可以通过使用条件值来实现相同功能。

The limitation that pthread_join() can join only with a specific thread ID is intentional. The idea is that a program should join only with the threads that it“knows” about. 
pthread_join的缺点就是只能join特定的threadID.这样设计的其中的原因就是一个程序只能Join它知道的线程。
The problem with a “join with any thread” operation stems from the fact that there is no hierarchy of threads, so such an operation could indeed join withany thread, including one that was privately created by a library function. (The condition-variable technique that we show in Section30.2.4allows a
thread to join only with any other thread that it knows about.) As a consequence, the library would no longer be able to join with that thread in order to
obtain its status, and it would erroneously try to join with a thread ID that had already been joined. In other words, a “join with any thread” operation is incompatible with modular program design.



下载地址见:http://blog.youkuaiyun.com/wdy_yx/article/details/41323387

























内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值