1.按序打印
思路:利用lock死锁阻塞的原理,先上两个锁,再2和3中试图打开这两个锁,再上一环解开下一环要打开的锁
代码
typedef struct {
// User defined data may be declared here.
pthread_mutex_t mutex1;//定义锁1
pthread_mutex_t mutex2;//定义锁2
pthread_mutex_t mutex3;
} Foo;
Foo* fooCreate() {
Foo* obj = (Foo*) malloc(sizeof(Foo));//创建结构体
pthread_mutex_init(&obj->mutex1,NULL);//初始化锁
pthread_mutex_init(&obj->mutex2, NULL);
pthread_mutex_init(&obj->mutex3, NULL);
// Initialize user defined data here.
//pthread_mutex_lock(&obj->mutex1);//将两把锁都上锁
pthread_mutex_lock(&obj->mutex2);
pthread_mutex_lock(&obj->mutex3);
return obj;
}
void first(Foo* obj) {
pthread_mutex_lock(&obj->mutex1);
// printFirst() outputs "first". Do not change or remove this line.
printFirst();
pthread_mutex_unlock(&obj->mutex1);
pthread_mutex_unlock(&obj->mutex2);
}
void second(Foo* obj) {
pthread_mutex_lock(&obj->mutex2);
//Do not change or remove this line.
printSecond();
pthread_mutex_unlock(&obj->mutex2);
pthread_mutex_unlock(&obj->mutex3);
}
void third(Foo* obj) {
//pthread_mutex_lock(&obj->mutex1);
pthread_mutex_lock(&obj->mutex3);
//outputs "third". Do not change or remove this line.
printThird();
pthread_mutex_unlock(&obj->mutex3);
}
void fooFree(Foo* obj) {
// User defined data may be cleaned up here.
pthread_mutex_destroy(&obj->mutex2);
pthread_mutex_destroy(&obj->mutex1);
pthread_mutex_destroy(&obj->mutex3);
free(obj);
}
- 交替打印字符串
需求:
编写一个可以从 1 到 n 输出代表这个数字的字符串的程序,但是:
如果这个数字可以被 3 整除,输出 “fizz”。
如果这个数字可以被 5 整除,输出 “buzz”。
如果这个数字可以同时被 3 和 5 整除,输出 “fizzbuzz”。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fizz-buzz-multithreaded
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
①设立4个条件变量保证在obj->num的自增1
②如果索引有效,则打印相关的值,并唤醒其他线程工作
③如果当前索引越界了,则停止线程,这一点很重要,不然会导致超时
typedef struct {
int k;
pthread_mutex_t mutex;
pthread_cond_t fizz;
pthread_cond_t buzz;
pthread_cond_t fizzbuzz;
pthread_cond_t number;
int num;
} FizzBuzz;
FizzBuzz* fizzBuzzCreate(int n) {
FizzBuzz* obj = (FizzBuzz*) malloc(sizeof(FizzBuzz));
obj->k = n;
obj->num=1;
pthread_mutex_init(&obj->mutex, NULL);
pthread_cond_init(&obj->buzz, NULL);
pthread_cond_init(&obj->fizz, NULL);
pthread_cond_init(&obj->fizzbuzz, NULL);
pthread_cond_init(&obj->number, NULL);
return obj;
}
void process(FizzBuzz*obj){
if(obj->num>obj->k){
pthread_cond_signal(&obj->fizzbuzz);
pthread_cond_signal(&obj->buzz);
pthread_cond_signal(&obj->fizz);
pthread_cond_signal(&obj->number);
}
if(0==obj->num%3&&0==obj->num%5){//可同时被3和5整除,唤醒fizzbuzz
pthread_cond_signal(&obj->fizzbuzz);
}
else if(0==obj->num%5){//能被5整除,唤醒buzz
pthread_cond_signal(&obj->buzz);
}
else if(0==obj->num%3){//能被3整除,唤醒fizz
pthread_cond_signal(&obj->fizz);
}
else{//都不能被整除
pthread_cond_signal(&obj->number);
}
}
// printFizz() outputs "fizz".
void fizz(FizzBuzz* obj) {
while(obj->num<=obj->k){
pthread_mutex_lock(&obj->mutex);
while(0!=obj->num%3&&obj->num<=obj->k){
pthread_cond_wait(&obj->fizz,&obj->mutex);
}
if(obj->num>obj->k){
pthread_mutex_unlock(&obj->mutex);
break;
}
else{
printFizz();
obj->num++;
process(obj);
pthread_mutex_unlock(&obj->mutex);
}
}
}
// printBuzz() outputs "buzz".
void buzz(FizzBuzz* obj) {
while(obj->num<=obj->k){
pthread_mutex_lock(&obj->mutex);
while(0!=obj->num%5&&obj->num<=obj->k){
pthread_cond_wait(&obj->buzz,&obj->mutex);
}
if(obj->num>obj->k){
pthread_mutex_unlock(&obj->mutex);
break;
}
else{
printBuzz();
obj->num++;
process(obj);
pthread_mutex_unlock(&obj->mutex);
}
}
}
// printFizzBuzz() outputs "fizzbuzz".
void fizzbuzz(FizzBuzz* obj) {
while(obj->num<=obj->k){
pthread_mutex_lock(&obj->mutex);
while(0!=obj->num%5 && 0!=obj->num%3 && obj->num<=obj->k){
pthread_cond_wait(&obj->fizzbuzz,&obj->mutex);
}
if(obj->num>obj->k){
pthread_mutex_unlock(&obj->mutex);
break;
}
else{
printFizzBuzz();
obj->num++;
process(obj);
pthread_mutex_unlock(&obj->mutex);
}
}
}
// You may call global function `void printNumber(int x)`
// to output "x", where x is an integer.
void number(FizzBuzz* obj) {
while(obj->num<=obj->k){
pthread_mutex_lock(&obj->mutex);
while((0==obj->num%5||0==obj->num%3)&&obj->num<=obj->k){
pthread_cond_wait(&obj->number,&obj->mutex);
}
if(obj->num>obj->k){
pthread_mutex_unlock(&obj->mutex);
break;
}
else{
printNumber(obj->num);
obj->num++;
process(obj);
pthread_mutex_unlock(&obj->mutex);
}
}
}
void fizzBuzzFree(FizzBuzz* obj) {//销毁锁和条件变量
if(obj!=NULL){
pthread_mutex_destroy(&obj->mutex);
pthread_cond_destroy(&obj->buzz);
pthread_cond_destroy(&obj->fizz);
pthread_cond_destroy(&obj->fizzbuzz);
pthread_cond_destroy(&obj->number);
}
}