
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
线程的学习与应用是许多软件编程开发程序员都需要熟练掌握的一个编程开发元素,下面我们就通过案例分析来简单了解一下,线程并发问题分析。
线程存储器模型:一组并发线程运行在一个进程的上下文中。每个线程都有自己独立的线程上下文,包括线程ID、栈、栈指针、程序计数器、条件码和通用目的寄存器值。每个线程和其他线程一起共享进程上下文剩余部分,其中包括整个用户虚拟地址空间,它是由只读文本(代码)、读写数据、堆以及所有的共享库代码和数据区域组成的,线程也共享相同的打开文件集合。
从实际操作角度来说,让一个线程去读写另一个线程的寄存器值是不可能的,另一方面,任何线程都可以访问共享虚拟内存的任意位置,如果某个线程修改了一个内存位置,那么其他每个线程终都能在它读这个位置时发现这个变化,因此寄存器是不共享的,而虚拟内存总是共享的。
各自独立的线程栈的内存模型不是那么整齐清楚,这些栈被保存在虚拟地址空间的栈区域中,并且通常是被相应的线程独立的访问的,我们说的通常不是总是,因为不同的线程栈是不对其他线程设防的,所以,如果一个线程以某一种方式得到一个指向其他线程栈的指针,那么它就可以读写这个栈的任何部分。
多线程的C程序中变量根据它们的存储类型被映射到虚拟内存。
(1)全局变量。全局变量是定义在函数之外的变量,在运行时,虚拟内存的读写区域只包含每个全局变量的一个实例,任何线程都可以引用。
(2)本地自动变量。本地自动变量就是定义在函数内部但是没有static属性的变量。在运行时,每个线程的栈都包含它自己的所有本地自动变量的实例,即使多个线程执行同一线程例程也是如此。
(3)本地静态变量。本地静态变量,是定义在函数内部并有static属性的变量。和全局变量一样,虚拟内存的读写区域只包含在程序中声明的每个本地静态变量的一个实例。例如,即使每个对等线程都声明了cnt,在运行时虚拟内存的读写区域也只有一个cnt的实例,每个对等线程都读写这个实例。
用信号量同步线程
共享变量虽然很方便但是会引入同步错误的问题,对于我们而言是没有办法预测操作系统是否将为你的线程选择一个正确的顺序,我们需要借助一种叫作进度图的方法来阐明这些正确或者不正确的指令顺序。
信号量提供了一种很方便的方法来确保对共享变量的互斥访问,基本思想是,将每个共享变量与一个信号量s联系起来,然后用P(s)和V(s)操作将相应的临界区包围起来。
除了提供互斥之外,信号量的另一个作用是调度对共享资源的访问,在这种场景中,一个线程用信号量操作来通知另一线程,程序中某个条件已经为真了,两个而有用的例子就是生产者-消费者和读者-写者问题。
生产者-消费者问题:
读者-写者问题:读者-写者问题是互斥问题的一个概括,一组并发的线程要访问一个共享对象,例如,一个主存中的数据结构或者一个磁盘上的数据库,有的线程只读对象,而其他的线程只修改对象。修改对象的叫作写者,只读对象的线程叫作读者。写者必须拥有对对象的独占的访问,而读者可以和无线个其他读者共享对象。一般来说,有无线多个并发的读者和写者。
【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。