读书人

Linux操作系统分析(九)- 多线程和线

发布时间: 2013-10-08 17:02:59 作者: rapoo

Linux操作系统分析(9)- 多线程和线程安全
进程和线程

进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放。可以认为进程是一个程序的一次执行过程。

线程是进程内的一个相对独立的可执行的单元。若把进程称为任务的话,那么线程则是应用中的一个子任务的执行。

线程和进程十分相似,不同的只是线程比进程小。首先,线程采用了多个线程可共享资源的设计思想;例如,它们的操作大部分都是在同一地址空间进行的。其次,从一个线程切换到另一线程所花费的代价比进程低。再次,进程本身的信息在内存中占用的空间比线程大,因此线程更能允分地利用内存。


多线程例子

使用Pthreads的主要动机是提高潜在程序的性能。 当与创建和管理进程的花费相比,线程可以使用操作系统较少的开销,管理线程需要较少的系统资源。

Pthreads定义了一套C语言的类型、函数与常量,它以pthread.h头文件和一个线程库实现。

     

代码一行行解释。

#1 包含pthread头文件,这个在linux中默认就有,无需配置安装。

#5 -11 定义线程函数,作为后面pthread_create的参数,pthread_exit()为终止当前线程。

#15 定义一个线程句柄数组。

#17-24 创建5个线程。

pthread_create参数:
thread:返回一个不透明的,唯一的新线程标识符。
attr:不透明的线程属性对象。可以指定一个线程属性对象,或者NULL为缺省值。
start_routine:线程将会执行一次的C函数。
arg: 传递给start_routine单个参数,传递时必须转换成指向void的指针类型。没有参数传递时,可设置为NULL。


pthread_create()函数允许程序员想线程的start routine传递一个参数。当多个参数需要被传递时,可以通过定义一个结构体包含所有要传的参数,然后用pthread_create()传递一个指向改结构体的指针,来打破传递参数的个数的限制。
所有参数都应该传引用传递并转化成(void*)。


线程安全

线程安全问题都是由全局变量及静态变量引起的。

若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

看一个向量点乘的例子:




在上面的代码中,将两个向量的点乘分别放到5个线程里分块完成,理想的情况下,计算速度提升了5倍。

在dotproduct函数中,操作dotstr的时候,使用了互斥锁。首先开启互斥 pthread_mutex_lock(&mutexsum),然后操作数据,最后打开互斥pthread_mutex_unlock(&mutexsum)。虽然在这里添不添加互斥没有关系,但如果对全局变量的操作更加复杂的时候,比如有乘除法的时候,互斥锁就变得很重要了。

在main函数中,pthread_attr_t表示线程属性结构体,使用的时候需要对此结构体进行初始化,初始化后使用,使用后还要进行去除初始化。pthread_attr_init:初始化,pthread_attr_destory:去除初始化。

设置线程分离状态的函数为pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)。第二个参数可选为PTHREAD_CREATE_DETACHED(分离线程)和 PTHREAD _CREATE_JOINABLE(非分离线程)。

pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果进程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。


参考

pthreads 的基本用法 - http://www.ibm.com/developerworks/cn/linux/l-pthred/

POSIX 多线程程序设计 - http://www.cnblogs.com/mywolrd/archive/2009/02/05/1930707.html


读书人网 >操作系统

热点推荐