内蒙古大学《计算机操作系统》上机实验指导06:Linux线程控制

上传人:东*** 文档编号:269980169 上传时间:2022-03-24 格式:DOC 页数:6 大小:51.50KB
返回 下载 相关 举报
内蒙古大学《计算机操作系统》上机实验指导06:Linux线程控制_第1页
第1页 / 共6页
内蒙古大学《计算机操作系统》上机实验指导06:Linux线程控制_第2页
第2页 / 共6页
内蒙古大学《计算机操作系统》上机实验指导06:Linux线程控制_第3页
第3页 / 共6页
内蒙古大学《计算机操作系统》上机实验指导06:Linux线程控制_第4页
第4页 / 共6页
内蒙古大学《计算机操作系统》上机实验指导06:Linux线程控制_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《内蒙古大学《计算机操作系统》上机实验指导06:Linux线程控制》由会员分享,可在线阅读,更多相关《内蒙古大学《计算机操作系统》上机实验指导06:Linux线程控制(6页珍藏版)》请在金锄头文库上搜索。

1、计算机操作系统上机实验实验6 Linux线程控制背景知识: 线程,是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。每一个程序都至少有一个线程,那就是程序本身。线程是程序中一个单一的顺序控制流程。在单个程序中同时运

2、行多个线程完成不同的工作,称为多线程。使用多线程的理由之一是和进程相比,它是一种非常节俭的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种昂贵的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。使用多线程的理由之二是线程

3、间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。除了以上所说的优点外,不和进程比较,多线程程序作为一种多任务、并发的工作方式,当然有以下的优点:1) 提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时

4、,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。2) 使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。3) 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。线程函数(1) 进程创建函数创建线程实际上就是确定调用该线程函数的入口点,这里通常使用的函数是pthread_create()。在线程创建以后,就开始运行相关的线程函数,在该函数运行完之后,该线程也就

5、退出了,这也是线程退出一种方法。所需头文件#include 函数原型int pthread_create (pthread_t *thread, pthread_attr_t *attr,void *(*start_routine)(void *), void *arg)函数传入值thread:线程标识符attr:线程属性设置(其具体设置参见9.2.3小节),通常取为NULLstart_routine:线程函数的起始地址,是一个以指向void的指针作为参数和返回值的函数指针arg:传递给start_routine的参数函数返回值成功:0出错:返回错误码(2) 进程退出函数线程退出时使用函数pt

6、hread_exit,是线程的主动行为。注意进程退出时使用exit函数,线程中用pthread_exit替代exit。所需头文件#include 函数原型void pthread_exit(void *retval)函数传入值retval:线程结束时的返回值,可由其他函数如pthread_join()来获取(3) 等待函数(等待一个线程的结束)由于一个进程中的多个线程共享数据段,因此通常在线程退出后,退出线程所占用的资源并不会随线程结束而释放。所有需要pthread_join函数来等待线程结束。类似于wait系统调用。所需头文件#include 函数原型int pthread_join (pt

7、hread_t th, void *thread_return)函数传入值th:等待线程的标识符thread_return:用户定义的指针,用来存储被等待线程结束时的返回值(不为NULL时)函数返回值成功:0出错:返回错误码(4) 互斥锁线程控制互斥锁是用一种简单的加锁方法来控制对共享资源的原子操作。这个互斥锁只有两种状态,也就是上锁和解锁,可以把互斥锁看作某种意义上的全局变量。在同一时刻只能有一个线程掌握某个互斥锁,拥有上锁状态的线程能够对共享资源进行操作。若其他线程希望上锁一个已经被上锁的互斥锁,则该线程就会挂起,直到上锁的线程释放掉互斥锁为止。可以说,这把互斥锁保证让每个线程对共享资源按

8、顺序进行原子操作。互斥锁机制主要包括下面的基本函数。n互斥锁初始化:pthread_mutex_init()n互斥锁上锁:pthread_mutex_lock()n互斥锁判断上锁:pthread_mutex_trylock()n互斥锁接锁:pthread_mutex_unlock()n消除互斥锁:pthread_mutex_destroy()其中,互斥锁可以分为快速互斥锁、递归互斥锁和检错互斥锁。这3种锁的区别主要在于其他未占有互斥锁的线程在希望得到互斥锁时是否需要阻塞等待。快速锁是指调用线程会阻塞直至拥有互斥锁的线程解锁为止。递归互斥锁能够成功地返回,并且增加调用线程在互斥上加锁的次数,而检

9、错互斥锁则为快速互斥锁的非阻塞版本,它会立即返回并返回一个错误信息。默认属性为快速互斥锁。所需头文件#include 函数原型int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)函数传入值mutex:互斥锁MutexattrPTHREAD_MUTEX_INITIALIZER:创建快速互斥锁PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP:创建递归互斥锁PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP:创建检错互斥锁函数返回

10、值成功:0出错:返回错误码所需头文件#include 函数原型int pthread_mutex_lock(pthread_mutex_t *mutex,)int pthread_mutex_trylock(pthread_mutex_t *mutex,)int pthread_mutex_unlock(pthread_mutex_t *mutex,)int pthread_mutex_destroy(pthread_mutex_t *mutex,)函数传入值mutex:互斥锁函数返回值成功:0出错:-1(5) 信号量线程控制信号量也就是操作系统中所用到的PV原子操作,它广泛用于进程或线程间的

11、同步与互斥。信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。这里先来简单复习一下PV原子操作的工作原理。PV原子操作是对整数计数器信号量sem的操作。一次P操作使sem减一,而一次V操作使sem加一。进程(或线程)根据信号量的值来判断是否对公共资源具有访问权限。当信号量sem的值大于等于零时,该进程(或线程)具有公共资源的访问权限;相反,当信号量sem的值小于零时,该进程(或线程)就将阻塞直到信号量sem的值大于等于0为止。PV原子操作主要用于进程或线程间的同步和互斥这两种典型情况。Linux实现了POSIX的无名信号量,主要用于线程间的互斥与同步。这里主要介绍几个常见函数。

12、nsem_init()用于创建一个信号量,并初始化它的值。nsem_wait()和sem_trywait()都相当于P操作,在信号量大于零时它们都能将信号量的值减一,两者的区别在于若信号量小于零时,sem_wait()将会阻塞进程,而sem_trywait()则会立即返回。nsem_post()相当于V操作,它将信号量的值加一同时发出信号来唤醒等待的进程。nsem_getvalue()用于得到信号量的值。nsem_destroy()用于删除信号量。所需头文件#include 函数原型int sem_init(sem_t *sem,int pshared,unsigned int value)函

13、数传入值sem:信号量指针pshared:决定信号量能否在几个进程间共享。由于目前Linux还没有实现进程间共享信号量,所以这个值只能够取0,就表示这个信号量是当前进程的局部信号量value:信号量初始化值函数返回值成功:0出错:-1所需头文件#include 函数原型int sem_wait(sem_t *sem)int sem_trywait(sem_t *sem)int sem_post(sem_t *sem)int sem_getvalue(sem_t *sem)int sem_destroy(sem_t *sem)函数传入值sem:信号量指针函数返回值成功:0出错:-1实验目的:学习

14、相关于线程的部分函数,可以在编程中实现对线程的初步操作。为学习进程间的互斥操作打下基础。实验要求:编写程序:1.使用线程解决生产者消费者问题。生产者生产物品用于消费者消费。生产者生产的商品只可以保存2个。生产者生产5次,消费者全部消费。消费者5次消费后死亡,生产者检测到消费者死亡后跟随死亡,并清空所有产品。2.使用线程模拟解决银行排队叫号问题。在银行中有一个叫号机,有一个10个座位的长椅,客户在叫号后如果无人在柜台前服务,就会去要求服务;如果柜台忙,则会找长椅入座;如果长椅满则会离开。要求屏显叫号过程,分析程序运行状况,并对程序作出评价。(实验报告中要求评价,前两条上机检查。)计算机操作系统实验报告姓名 学号 成绩 年 月 日一、 程序功能二、 程序框图或描述三、 程序代码第 6 页 共 6 页

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > 计算机原理

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号