




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1 引言线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者。传统的Unix也支持线程的概念,但是在一个进程(process)中只允许有一个线程,这样多线程就意味着多进程。现在,多线程技术已经被许多操作系统所支持,包括Windows/NT,当然,也包括Linux。为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应该选用多线程?我们首先必须回答这些问题。使用多线程的理由之一是和进程相比,它是一种非常节俭的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,
2、建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种昂贵的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。使用多线程的理由之二是线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,
3、所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。除了以上所说的优点外,不和进程比较,多线程程序作为一种多任务、并发的工作方式,当然有以下的优点:1) 提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。2)
4、使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。3) 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。下面我们先来尝试编写一个简单的多线程程序。2 简单的多线程编程Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。顺便说一下,Linux下pthread的实现是通过系统调用clone()来实现的。clone()是Linux所特有的系统调用,它的使用方式类似f
5、ork,关于clone()的详细情况,有兴趣的读者可以去查看有关文档说明。下面我们展示一个最简单的多线程程序example1.c。/* example.c*/#include#includevoid thread(void)int i;for(i=0;i3;i+)printf(This is a pthread.n);int main(void)pthread_t id;int i,ret;ret=pthread_create(&id,NULL,(void *) thread,NULL);if(ret!=0)printf (Create pthread error!n);exit (1);fo
6、r(i=0;inext;Process_job(p);Free(p);当线程1处理完第一步,也就是Item *p=queue_list后,这时候系统停止线程1的运行,改而运行线程2。线程2照样取出头节点,然后进行处理,最后释放了该节点。过了段时间,线程1重新得到运行。而这个时候,其实p所指向的节点已经被线程2释放掉,而线程1对此毫无知晓。他会接着运行process_job(p)。而这将导致无法预料的后果!对于这种情况,系统给我们提供了互斥量。你在取出头节点前必须要等待互斥量,如果此时有其他线程已经获得该互斥量,那么线程将会阻塞在这个地方。只有等到其他线程释放掉该互斥量后,你的线程才有可能得到该
7、互斥量。为什么是可能了?因为可能此时有不止你一个线程在等候该互斥量,而系统无法保证你的线程将会优先运行。互斥量的类型为pthread_mutex_t。你可以声明多个互斥量。在声明该变量后,你需要调用pthread_mutex_init()来创建该变量。pthread_mutex_init的格式如下:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr);第一个参数,mutext,也就是你之前声明的那个互斥量,第二个参数为该互斥量的属性。这个将在后面详细讨论。在创建该互斥量之后,你
8、便可以使用它了。要得到互斥量,你需要调用下面的函数:int pthread_mutex_lock(pthread_mutex_t *mutex);该函数用来给互斥量上锁,也就是我们前面所说的等待操作。互斥量一旦被上锁后,其他线程如果想给该互斥量上锁,那么就会阻塞在这个操作上。如果在此之前该互斥量已经被其他线程上锁,那么该操作将会一直阻塞在这个地方,直到获得该锁为止。在得到互斥量后,你就可以进入关键代码区了。同样,在操作完成后,你必须调用下面的函数来给互斥量解锁,也就是前面所说的释放。这样其他等待该锁的线程才有机会获得该锁,否则其他线程将会永远阻塞。int pthread_mutex_unloc
9、k(pthread_mutex_t *mutex);下面给出一个简单的例子:#include #include struct job /* Link field for linked list. */struct job* next;/* Other fields describing work to be done. */;/* A linked list of pending jobs. */struct job* job_queue;/* A mutex protecting job_queue. */pthread_mutex_t job_queue_mutex = PTHREAD_M
10、UTEX_INITIALIZER;/* Process queued jobs until the queue is empty. */void* thread_function (void* arg)while (1) struct job* next_job;/* Lock the mutex on the job queue. */pthread_mutex_lock (&job_queue_mutex);/* Now its safe to check if the queue is empty. */if (job_queue = NULL)next_job = NULL;else
11、/* Get the next available job. */next_job = job_queue;/* Remove this job from the list. */job_queue = job_queue-next;/* Unlock the mutex on the job queue because were done with thequeue for now. */pthread_mutex_unlock (&job_queue_mutex);/* Was the queue empty? If so, end the thread. */if (next_job =
12、 NULL)break;/* Carry out the work. */process_job (next_job);/* Clean up. */free (next_job);return NULL; 在这个例子中我们使用了下面一条语句:pthread_mutex_t job_queue_mutex = PTHREAD_MUTEX_INITIALIZER; 他的作用和调用pthread_mutex_init()函数一样。 如果一个线程已经给一个互斥量上锁了,后来在操作的过程中又再次调用了该上锁的操作,那么该线程将会无限阻塞在这个地方,从而导致死锁。怎么变了?这就需要我们之前所提到的互斥量的属性。互斥量分为下面三种:l 快速型。这种类型也是默认的类型。该线程的行为正如上面所说的。l 递归型。如果遇到我们上面所提到的死锁情况,同一线程循环给互斥量上
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 地暖太阳能工程施工方案
- 管道跨越施工方案
- 医疗机构水污染物排放的法律责任与监管措施
- 【专精特新】印制电路板行业市场份额证明材料(智研咨询发布)
- 食品加工企业食品安全事件应急预案
- 基于大观念的高中英语单元整体教学设计探究
- 湖北省2024-2025学年高二上学期1月期末物理试题(原卷版)
- 四川罗渡中学20172018人教地理必修二综合训练(四)及解析
- 北京市房山区2024-2025学年高三上学期期末学业水平调研(二)物理试卷2
- 安徽省亳州市2024-2025学年高二上学期期末考试地理试卷
- 220kV输电线路工程质量通病防治措施
- 【EHS流程图】建设项目职业卫生“三同时”工作流程图(9页)
- 迈达斯建模(贝雷梁、钢栈桥)
- [考研英语]商志英语作文模板
- Fluent出入口边界条件设置及实例解析
- 模拟追溯演练报告(成品到原料)
- 常用一线降压药一览表
- IATF16949-2016内部审核方案
- 权威实验室CMA资质认定程序文件模板
- 平面机构简图及自由分解PPT课件
- 工业园区提升改造项目可行性研究报告模板
评论
0/150
提交评论