题目为:用三个线程分别打印’A’、’B’、’C’,线程1打印A,线程2打印B,线程3打印C,请实现三个线程同时启动并协作始终打印 ABCABCABC….,是在牛客网上看到的阿里一面的题目。
首先要实现轮次有序打印ABC,就必须让线程1先执行,然后再让线程2执行,最后再让线程3执行,最后再回到线程1,以此循环往复。所以就需要保证线程的执行顺序,且单个线程在执行的时候,不能受到其他两个线程的干扰,那比较容易想到采用锁。
那肯定不能单纯的让三个线程去竞争锁,因为无法保证线程1首先拿到锁,再到线程2和线程3,所以需要有个flag来标记。下面先看
第一种实现方法,单纯使用互斥量+一个标记
#include <iostream>
#include <pthread.h>
using namespace std;
pthread_mutex_t mymutex; //互斥量
int ct = 1; //全局变量计数
void* thread1(void* arg){ //线程1打印'A'
while(1){
pthread_mutex_trylock(&mymutex);
while(ct == 1){
cout << 'A';
++ct;
}
pthread_mutex_unlock(&mymutex);
}
}
void* thread2(void* arg){ //线程2打印'B'
while(1){
pthread_mutex_trylock(&mymutex);
while(ct == 2){
cout << 'B';
++ct;
}
pthread_mutex_unlock(&mymutex);
}
}
void* thread3(void* arg){ //线程3打印'C'
while(1){
pthread_mutex_trylock(&mymutex);
while(ct == 3){
cout << 'C' << ' ';
ct = 1; //重置ct
}
pthread_mutex_unlock(&mymutex);
}
}
int main(){
pthread_t t1;
pthread_t t2;
pthread_t t3;
pthread_mutex_init(&mymutex, NULL);
pthread_create(&t1,NULL,thread1,NULL);
pthread_create(&t2,NULL,thread2,NULL);
pthread_create(&t3,NULL,thread3,NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
return 0;
}
为了呈现效果更清晰,用一个空格隔开)
第二种实现方法,采用条件变量 + 互斥锁
#include <iostream>
#include <pthread.h>
using namespace std;
pthread_cond_t mycond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mymutex;
int ct = 0;
void* mythread1(void *arg){
while(1){
pthread_mutex_lock(&mymutex);
while(ct % 3 != 0){
pthread_cond_wait(&mycond, &mymutex); //还没轮到,继续等待
}
cout << 'A';
++ct;
pthread_mutex_unlock(&mymutex);
pthread_cond_broadcast(&mycond);
}
}
void* mythread2(void *arg2){
while(1){
pthread_mutex_lock(&mymutex);
while(ct % 3 != 1){
pthread_cond_wait(&mycond, &mymutex);
}
cout << 'B';
++ct;
pthread_mutex_unlock(&mymutex);
pthread_cond_broadcast(&mycond);
}
}
void* mythread3(void *arg3){
while(1){
pthread_mutex_lock(&mymutex);
while(ct % 3 != 2){
pthread_cond_wait(&mycond, &mymutex);
}
cout << 'C' << endl;
++ct;
pthread_mutex_unlock(&mymutex);
pthread_cond_broadcast(&mycond);
}
}
int main(){
pthread_mutex_init(&mymutex, NULL);
pthread_t t1;
pthread_t t2;
pthread_t t3;
pthread_create(&t1, NULL, mythread1, NULL);
pthread_create(&t2, NULL, mythread2, NULL);
pthread_create(&t3, NULL, mythread3, NULL);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
return 0;
}