山东大学操作系统课程设计源码分析 Thread(3)

本文详细分析了操作系统课程设计中的线程同步工具,包括信号量Semaphore、互斥锁Lock、条件量Condition和同步列表SynchList。重点讨论了它们在多线程环境下的工作原理和作用,如Semaphore的P/V操作、Lock的互斥性、Condition的等待与唤醒机制,以及SynchList如何实现线程安全的数据管理。通过对这些同步工具的理解,有助于深入掌握并发编程和管程模型。
摘要由CSDN通过智能技术生成

一、写在前面

        上一节我们分析了线程调度器Scheduler类和线程切换函数SWITCH与线程生命周期逻辑函数ThreadRoot函数,了解了线程从创建到销毁的过程与线程的寄存器信息是如何保存与恢复的.在本节我们将分析该包下最后的两个类.

二、源码分析

         1、信号量:Semaphore

class Semaphore {
  public:
    Semaphore(const char* debugName, int initialValue);	// set initial value
    ~Semaphore();   					// de-allocate semaphore
    char* getName() { return name;}			// debugging assist
    
    void P();	 // these are the only operations on a semaphore
    void V();	 // they are both *atomic*
    
  private:
    char* name;  // useful for debugging
    int value;         // semaphore value, always >= 0
    List *queue;       // threads waiting in P() for the value to be > 0
};

        信号量是为了解决同步/互斥问题而产生的,信号量的存在能够避免并发线程的执行顺序出现异常从而得到预期之外的效果.Semaphore类中的数据成员有name,value和queue三个,name是用于进行调式的信号量名称,value为信号量目前的取值,queue为在该信号量上阻塞的线程列表.

        信号量提供了两个基本的方法P和V,P函数代表请求资源的操作,如果资源不足则使该线程阻塞在该信号量中的等待队列中.V函数代表释放资源的操作,如果阻塞队列中有线程在等待则取出一个后将其唤醒.

        Semaphore类中还提供了getName方法用于获取调试名称.


Semaphore::Semaphore(const char* debugName, int initialValue)
{
    name = (char*)debugName;
    value = initialValue;
    queue = new List;
}


Semaphore::~Semaphore()
{
    delete queue;
}


void
Semaphore::P()
{
    IntStatus oldLevel = interrupt->SetLevel(IntOff);	// disable interrupts
    
    while (value == 0) { 			// semaphore not available
	queue->Append((void *)currentThread);	// so go to sleep
	currentThread->Sleep();
    } 
    value--; 					// semaphore available, 
						// consume its value
    
    (void) interrupt->SetLevel(oldLevel);	// re-enable interrupts
}


void
Semaphore::V()
{
    Thread *thread;
    IntStatus oldLevel = interrupt->SetLevel(IntOff);

    thread = (Thread *)queue->Remove();
    if (thread != NULL)	   // make thread ready, consuming the V immediately
	scheduler->ReadyToRun(thread);
    value++;
    (void) interrupt->SetLevel(oldLevel);
}

        Semaphore的构造函数接收一个字符数组作为调试名称和一个整型值作为该信号量代表的资源的初始值.然后构造一个列表用于存放阻塞的线程.析构函数中将阻塞队列释放.

        进入P函数后首先关中断确保P操作是原子的,然后进入while循环,在信号量的value值等于0是不断重复,在每

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值