最近离职换工作,一次笔试中遇到了多线程同步的经典编程题:三个线程A、B、C,分别打印‘A’、‘B’、‘C’,要求按照ABC的顺序打印10遍。笔试当中代码写了一半,着急下一轮面试就没写完交卷了。回来上网搜下别人的实现方式,发现用C++的POSIX调用的实现很多都是错的。一看作者就没有真正的在环境上验证过,想当然的就把代码贴到了博客上。于是,就像在这里完成笔试中的代码,给大家一个POSIX的实现例子。
这道题的解题思路其实很明确,就是想要B、C线程阻塞,A线程打印完‘A’后唤醒B线程然后阻塞,B线程打印完‘B’后唤醒C线程然后阻塞,依次类推C打印完毕后再唤醒A。这种情形用条件变量是比较符合的。代码如下:
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define DEBUG
1
pthread_mutex_t Alock
=
PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t Block
=
PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t Clock
=
PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t AReady
=
PTHREAD_COND_INITIALIZER;
pthread_cond_t BReady
=
PTHREAD_COND_INITIALIZER;
pthread_cond_t CReady
=
PTHREAD_COND_INITIALIZER;
void
*
thread_A(
void
*
arg)
{
//A线程
for
(
int
i
=
0
; i
<
10
; i
++
)
{
pthread_mutex_lock(
&
Alock);
if
(i
!=
0
)
//第一个循环不判断条件变量
pthread_cond_wait(
&
AReady,
&
Alock);
cout
<<
"A"
<<
endl
<<
flush;
pthread_mutex_unlock(
&
Alock);
pthread_cond_signal(
&
BReady);
}
return
(
void
*
)
0
;
}
void
*
thread_B(
void
*
arg)
{
//B线程
for
(
int
i
=
0
; i
<
10
; i
++
)
{
pthread_mutex_lock(
&
Block);
pthread_cond_wait(
&
BReady,
&
Block);
cout
<<
"B"
<<
endl
<<
flush;
pthread_mutex_unlock(
&
Block);
pthread_cond_signal(
&
CReady);
}
return
(
void
*
)
0
;
}
void
*
thread_C(
void
*
arg)
{
//C线程
for
(
int
i
=
0
; i
<
10
; i
++
)
{
pthread_mutex_lock(
&
Clock);
pthread_cond_wait(
&
CReady,
&
Clock);
cout
<<
"C"
<<
endl
<<
flush;
pthread_mutex_unlock(
&
Clock);
pthread_cond_signal(
&
AReady);
}
return
(
void
*
)
0
;
}
int
main()
{
pthread_t tid[
3
];
void
*
tret;
pthread_create(
&
tid[
0
],
NULL
, thread_C,
NULL
);
pthread_create(
&
tid[
1
],
NULL
, thread_B,
NULL
);
pthread_create(
&
tid[
2
],
NULL
, thread_A,
NULL
);
for
(
int
i
=
0
; i
<
3
; i
++
)
pthread_join(tid[i],
&
tret);
return
0
;
}