在nachos的sysnch文件中定义了解决同步线程的三种方式:信号semaphores,锁locks,环境变量condition variables。
semaphores的实现nachos已经给出:
//sysnch.h
// value的值是非负整数. P和V操作都是原子的,不可中断
class Semaphore {
public:
Semaphore(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
};
//sysnch.cc
//构造函数,初始化value和队列
Semaphore::Semaphore(char* debugName, int initialValue)
{
name = debugName;
value = initialValue;
queue = new List;
}
//析构函数,删除队列
Semaphore::~Semaphore()
{
delete queue;
}
//P操作
void
Semaphore::P()
{
IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts
//当value = 0时,信号被占用,在等待队列中增加一个线程,并将线程进入睡眠状态
while (value == 0) { // semaphore not available
queue->Append((void *)currentThread); // so go to sleep
currentThread->Sleep();
}
//当value != 0时,跳出循环 将value值 -1
value--; // semaphore available,
// consume its value
//恢复中断
(void) interrupt->SetLevel(oldLevel); // re-enable interrupts
}
//V操作
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);
}
synchlist 维护了同步访问队列.
1. 线程必须等待列表中包含元素的之后才能进行删除操作
2. 同一时间内只有一个线程可以访问列表
class SynchList {
public:
SynchList(); // initialize a synchronized list
~SynchList(); // de-allocate a synchronized list
void Append(void *item); // append item to the end of the list,
// and wake up any thread waiting in remove
// 在列表中增加一个项目,唤醒要进行删除操作的线程
void *Remove(); // remove the first item from the front of
// the list, waiting if the list is empty
//在列表中删除一个项目,如果列表为空,等待
void Mapcar(VoidFunctionPtr func);
// apply function to every item in the list
// 使得列表中每个条目应用该方法
private:
List *list; // the unsynchronized list 不同步列表
Lock *lock; // enforce mutual exclusive access to the list,互斥锁
Condition *listEmpty; // wait in Remove if the list is empty 控制变量
};
//synchlist.cc
//向列表中增加一条
void
SynchList::Append(void *item)
{
lock->Acquire(); // enforce mutual exclusive access to the list
list->Append(item);
listEmpty->Signal(lock); // wake up a waiter, if any
lock->Release();
}
//移除列表中一条
void *
SynchList::Remove()
{
void *item;
lock->Acquire(); // enforce mutual exclusion
while (list->IsEmpty())
listEmpty->Wait(lock); // wait until list isn't empty
item = list->Remove();
ASSERT(item != NULL);
lock->Release();
return item;
}
semaphores的实现nachos已经给出:
//sysnch.h
// value的值是非负整数. P和V操作都是原子的,不可中断
class Semaphore {
public:
Semaphore(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
};
//sysnch.cc
//构造函数,初始化value和队列
Semaphore::Semaphore(char* debugName, int initialValue)
{
name = debugName;
value = initialValue;
queue = new List;
}
//析构函数,删除队列
Semaphore::~Semaphore()
{
delete queue;
}
//P操作
void
Semaphore::P()
{
IntStatus oldLevel = interrupt->SetLevel(IntOff); // disable interrupts
//当value = 0时,信号被占用,在等待队列中增加一个线程,并将线程进入睡眠状态
while (value == 0) { // semaphore not available
queue->Append((void *)currentThread); // so go to sleep
currentThread->Sleep();
}
//当value != 0时,跳出循环 将value值 -1
value--; // semaphore available,
// consume its value
//恢复中断
(void) interrupt->SetLevel(oldLevel); // re-enable interrupts
}
//V操作
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);
}
synchlist 维护了同步访问队列.
1. 线程必须等待列表中包含元素的之后才能进行删除操作
2. 同一时间内只有一个线程可以访问列表
class SynchList {
public:
SynchList(); // initialize a synchronized list
~SynchList(); // de-allocate a synchronized list
void Append(void *item); // append item to the end of the list,
// and wake up any thread waiting in remove
// 在列表中增加一个项目,唤醒要进行删除操作的线程
void *Remove(); // remove the first item from the front of
// the list, waiting if the list is empty
//在列表中删除一个项目,如果列表为空,等待
void Mapcar(VoidFunctionPtr func);
// apply function to every item in the list
// 使得列表中每个条目应用该方法
private:
List *list; // the unsynchronized list 不同步列表
Lock *lock; // enforce mutual exclusive access to the list,互斥锁
Condition *listEmpty; // wait in Remove if the list is empty 控制变量
};
//synchlist.cc
//向列表中增加一条
void
SynchList::Append(void *item)
{
lock->Acquire(); // enforce mutual exclusive access to the list
list->Append(item);
listEmpty->Signal(lock); // wake up a waiter, if any
lock->Release();
}
//移除列表中一条
void *
SynchList::Remove()
{
void *item;
lock->Acquire(); // enforce mutual exclusion
while (list->IsEmpty())
listEmpty->Wait(lock); // wait until list isn't empty
item = list->Remove();
ASSERT(item != NULL);
lock->Release();
return item;
}