给你一个类:
public class Foo {
public void first() { print("first"); }
public void second() { print("second"); }
public void third() { print("third"); }
}
三个不同的线程 A、B、C 将会共用一个 Foo 实例。
线程 A 将会调用 first() 方法
线程 B 将会调用 second() 方法
线程 C 将会调用 third() 方法
请设计修改程序,以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。
提示:
尽管输入中的数字似乎暗示了顺序,但是我们并不保证线程在操作系统中的调度顺序。
你看到的输入格式主要是为了确保测试的全面性。
方法一:信号量while?
typedef struct {
// User defined data may be declared here.
int mutex_1;
// int mutex_2;
} Foo;
Foo* fooCreate() {
Foo* obj = (Foo*) malloc(sizeof(Foo));
// Initialize user defined data here.
obj->mutex_1 = 1;
// obj->mutex_2 = 1;//初始化
return obj;
}
void first(Foo* obj) {
// printFirst() outputs "first". Do not change or remove this line.
while(obj->mutex_1!=1);
printFirst();
obj->mutex_1 = 2;
}
void second(Foo* obj) {
// printSecond() outputs "second". Do not change or remove this line.
while(obj->mutex_1!=2);
printSecond();
obj->mutex_1 = 3;
}
void third(Foo* obj) {
while(obj->mutex_1!=3);
// printThird() outputs "third". Do not change or remove this line.
printThird();
}
void fooFree(Foo* obj) {
// User defined data may be cleaned up here.
free(obj);
}
方法二:信号量
#include
信号量的数据类型为结构sem_t,它本质上是一个长整型的数。
函数sem_init()用来初始化一个信号量。它的原型为:int sem_init __P ((sem_t *__sem, int __pshared, unsigned int __value));sem为指向信号量结构的一个指针;pshared不为0时此信号量在进程间共享,否则只能为当前进程的所有线程共享;value给出了信号量的初始值。信号量用sem_init函数创建的,下面是它的说明:
int sem_init (sem_t *sem, int pshared, unsigned int value); 这个函数的作用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值。pshared参数控制着信号量的类型。如果 pshared的值是0,就表示它是当前里程的局部信号量;否则,其它进程就能够共享这个信号量。我们现在只对不让进程共享的信号量感兴趣。 (这个参数 受版本影响), pshared传递一个非零将会使函数调用失败,属于无名信号量。
函数sem_post( sem_t *sem )用来增加信号量的值。当有线程阻塞在这个信号量上时,调用这个函数会使其中的一个线程不在阻塞,选择机制同样是由线程的调度策略决定的。int sem_post(sem_t *sem);sem_post() 成功时返回 0;错误时,信号量的值没有更改,-1 被返回,并设置errno 来指明错误。错误 EINVAL sem 不是一个有效的信号量。 EOVERFLOW 信号量允许的最大值将要被超过。
函数sem_wait( sem_t *sem )被用来阻塞当前线程直到信号量sem的值大于0,解除阻塞后将sem的值减一,表明公共资源经使用后减少。
函数sem_destroy(sem_t *sem)用来释放信号量sem,属于无名信号量。
typedef struct {
// User defined data may be declared here.
sem_t one;
sem_t two;
} Foo;
Foo* fooCreate() {
Foo* obj = (Foo*) malloc(sizeof(Foo));
sem_init(&(obj->one), 0, 0);
sem_init(&(obj->two), 0, 0);
// Initialize user defined data here.
return obj;
}
void first(Foo* obj) {
// printFirst() outputs "first". Do not change or remove this line.
printFirst();
sem_post(&(obj->one));
}
void second(Foo* obj) {
// printSecond() outputs "second". Do not change or remove this line.
sem_wait(&(obj->one));
printSecond();
sem_post(&(obj->two));
}
void third(Foo* obj) {
sem_wait(&(obj->two));
// printThird() outputs "third". Do not change or remove this line.
printThird();
}
void fooFree(Foo* obj) {
// User defined data may be cleaned up here.
sem_destroy(&(obj->one));
sem_destroy(&(obj->two));
}
方法三:线程
typedef struct {
pthread_mutex_t mutex_1;
pthread_mutex_t mutex_2; //创建互斥锁
} Foo;
Foo* fooCreate() {
Foo* obj = (Foo*) malloc(sizeof(Foo));
pthread_mutex_init(&obj->mutex_1, NULL);
pthread_mutex_init(&obj->mutex_2, NULL);
pthread_mutex_lock(&obj->mutex_1);
pthread_mutex_lock(&obj->mutex_2);
return obj;
}
void first(Foo* obj) {
printFirst();
pthread_mutex_unlock(&obj->mutex_1);
}
void second(Foo* obj) {
pthread_mutex_lock(&obj->mutex_1); //阻塞调用 获取锁
printSecond();
pthread_mutex_unlock(&obj->mutex_1);
pthread_mutex_unlock(&obj->mutex_2);
}
void third(Foo* obj) {
pthread_mutex_lock(&obj->mutex_2);
printThird();
pthread_mutex_unlock(&obj->mutex_2); //释放互斥锁
}
void fooFree(Foo* obj) {
pthread_mutex_destroy(&obj->mutex_1);
pthread_mutex_destroy(&obj->mutex_2); //销毁互斥锁
free(obj);
}