首页 > 其他分享 >操作系统导论习题解答(27. Thread API)

操作系统导论习题解答(27. Thread API)

时间:2022-10-14 19:26:16浏览次数:44  
标签:线程 27 Thread int lock mutex pthread cond 习题

Interlude: Thread API

带着两个问题学习本章节:

  1. OS创造和控制线程预留了什么接口?
  2. 这些接口是如何被设计以实现易用性和实用性?

1. Thread Creation

在这里插入图片描述

2. Thread Completion

在这里插入图片描述
在这里插入图片描述

3. Locks

除了创建和加入线程,另一个最有用的函数集就是为了使关键部分互斥的lcoks
下面是一对函数

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

上述一对函数的使用非常简单,就是把关键部分的代码置于其中:
在这里插入图片描述
当然,如果一个线程已经调用了lock,那么其他线程如果想调用lock的话就必须等待上一个调用lock的线程unlock。

不幸的是,该代码被两个重要问题破坏了:

  1. lack of proper initialization
  2. it fails to check error codes when calling lock and unlock

解决第一个问题的方法有两种初始化(静态和动态分配)。

// 静态分配
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
// 动态分配
int rc = pthread_mutex_init(&lock, NULL);
assert(rc == 0);
pthread_mutex_destroy(rc);	// 记得最后对动态分配要回收

简单程序使用assert,当出现问题时,更复杂的程序不是简单的退出,而是检查错误,并在调用不成功时进行适当处理。下面是一个简单程序

在这里插入图片描述
关于lock还有两个函数可调用:

int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec *abs_timeout);

这两个调用函数用于lcok获取。如果已持有lock,那么trylock将返回失败;获取lock的timedlock当超时或者获取lock后返回。

4. Condition Variables

当线程之间必须进行某种类型的信号传递时,如果一个线程在等待另一个线程做一些事情才能继续执行,则condition variables非常有用。希望以这种方式进行交互的程序使用如下可调用函数:

int pthread_cond_wait(pthread_cont_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);

第一个pthread_cond_wait使调用线程进入睡眠状态,等待其他线程发出信号。
如下所示
在这里插入图片描述
为了唤醒上述进入等待(睡眠)状态线程,有如下代码:

在这里插入图片描述
值得注意的是为了防止race condition,我们把condition variable放置在lock中

对于pthread_cond_waitpthread_cond_signal来说,传递参数不同。如下所示

// wait多了一个lock参数是因为当调用该函数时就进行unlock
// 然后传入的lock参数与phread_mutex_unlock(&lock)进行匹配
pthread_cond_wait(&cond, &lock);
pthread_cond_signal(&cond);

其实,单从代码的角度来说,可以把上述代码的while循环改写成如下:

while (ready == 0)
	;	// spin

但是,最好不要如此做。有如下几个原因:

  1. 它在许多情况下性能不佳(长时间循环只会浪费CPU周期)
  2. 容易出错

标签:线程,27,Thread,int,lock,mutex,pthread,cond,习题
From: https://www.cnblogs.com/astralcon/p/16792716.html

相关文章