1、很多数据结构在设计与实现时没有考虑如何保证并发访问时的正确性。而在多核中使用这些数据结构就必须修改代码以保证线程安全。下面代码片段展示了一个栈的实现,请分析该实现是否线程安全并解释原因。
1 typedef struct Node {
2 struct Node *next;
3 int value;
4 } Node;
5
6 void push (Node **top_ptr, Node *n) {
7 n->next=*top_ptr;
8 *top_ptr=n;
9 }
10
11 Node *pop (Node **top_ptr) {
12 if (*top_ptr==NULL)
13 return NULL;
14 Node *p=*top_ptr;
15 *top_ptr=(*top_ptr)->next;
16 return p;
17 }
不安全 因为当多个进程同时入栈出栈操作时候就会发生错误,应该设置信号量,在push和pop函数的开头加上P(S),在push和pop函数结束的位置加上V(S),这样就可以实现多个线程的互斥访问,保证安全
2、两个线程thread1和thread2所执行的函数,以及在执行这两个线程之前的初始化代码init,如下面代码段所示。如果我们需要保证两个线程都一定可以终止运行。请填写下面代码中空出的部分。注意,在thread1与thread2函数中,每个空位上只能填写信号量的signal()和wait()操作,但操作数量不限。
1 int x=1;
2 struct sem a, b, c;
3
4 void init ()
5 {
6 a->value= 2 ;
7 b->value= 1 ;
8 c->value= -1 ;
9 }
10
11 void thread1()
12 {
13 while(x!=12){
14 ++wait(a)++ ++; wait(b)++ ;
15 x=x*2;
16 ++signal(b)++ ++; signal(c)++ ;
17 }
18 exit(0);
19 }
20
21 void thread2()
22 {
23 while(x!=12){
24 ++wait(c) ; wait(b)++ ;
25 x=x*3;
26 ++signal(b)++ ++; signal(c)++ ;
27 }
28 exit(0);
29 }