天天看点

Pthread 用法笔记

从技术上讲,一个线程被定义为一个独立的指令流。

一个进程可以包含一个或多个线程。

线程操作包括线程创建,终止,同步(连接,阻塞),调度,数据管理和进程交互。

进程内的所有线程共享:

相同的地址空间

信号

文件描述符

工作目录

用户和组 ID

每个线程具有单独的:

堆栈指针

寄存器

调度属性(如策略或优先级)

线程特定的数据

上下文切换的开销减小,提高了效率。

共享存储器,方便构造并发服务器。

同时访问同一个变量的冲突。

缺乏健壮性,一个线程故障可能就需要终止整个进程。

POSIX 线程库是 C/C++ 的基于标准的线程API。

利用它我们可以操作线程,开发并行处理的程序。

一个简单的例子:

上面我们用到了 <code>pthread_create</code> 来创建线程。

线程函数的参数必须通过引用传递并转换为<code>(void *)</code>。

若要传递多个参数,可创建一个包含所有参数的结构体,再传递指向该结构体的指针。

如果传递的参数是一个变量的地址,由于这是共享内存空间,变量对所有线程可见,很有可能在新线程访问它之前,此内存位置的值发生了更改。

线程正常执行完后返回。

线程调用 <code>pthread_exit</code>。

线程被另一个线程通过 <code>pthread_cancel</code> 取消。

整个进程因调用 <code>exec()</code> 或 <code>exit()</code> 而终止。

<code>main()</code> 先完成,且没有显式调用 <code>pthread_exit</code> 。

如果没有显式地调用 <code>pthread_exit()</code>, <code>main()</code> 就会在它产生的线程之前完成,那么所有线程都将终止。

显示调用 <code>pthread_exit()</code>,则<code>main()</code> 会在结束前等待所有线程执行完毕。

我们也可以在 <code>main()</code> 中调用 <code>pthread_join(t, NULL);</code> 来连接子线程,连接后,当前线程就会阻塞并等待子线程 t 的结束。

另外创建时线程时可以通过线程属性指定是否可被连接。

Unix 的常见的线程同步机制:互斥(mutex)、信号量(semaphore)和条件变量(condition variable)。

互斥锁:阻止其他线程访问变量。

连接(join):让一个线程等待,直到其他人终止。(上面已经提到)

条件变量:数据类型 <code>pthread_cond_t</code>。

Mutex是“互斥”(mutual exclusion)的缩写。

互斥变量必须声明为<code>pthread_mutex_t</code>类型,并且必须在可以使用它们之前进行初始化。有两种方法来初始化互斥变量:

<code>pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;</code>

使用<code>pthread_mutex_init()</code>。该方法允许设置互斥对象属性 attr。

互斥变量最初是未上锁的。

一个条件变量总是与一个互斥锁一起使用。

参考1. POSIX thread (pthread) libraries

参考2. POSIX Threads Programming

┆凉┆暖┆降┆等┆幸┆我┆我┆里┆将┆ ┆可┆有┆谦┆戮┆那┆ ┆大┆始┆ ┆然┆

┆薄┆一┆临┆你┆的┆还┆没┆ ┆来┆ ┆是┆来┆逊┆没┆些┆ ┆雁┆终┆ ┆而┆

┆ ┆暖┆ ┆如┆地┆站┆有┆ ┆也┆ ┆我┆ ┆的┆有┆精┆ ┆也┆没┆ ┆你┆

┆ ┆这┆ ┆试┆方┆在┆逃┆ ┆会┆ ┆在┆ ┆清┆来┆准┆ ┆没┆有┆ ┆没┆

┆ ┆生┆ ┆探┆ ┆最┆避┆ ┆在┆ ┆这┆ ┆晨┆ ┆的┆ ┆有┆来┆ ┆有┆

┆ ┆之┆ ┆般┆ ┆不┆ ┆ ┆这┆ ┆里┆ ┆没┆ ┆杀┆ ┆来┆ ┆ ┆来┆

继续阅读