leetcode 线程题 1114. 按序打印

简介: leetcode 线程题 1114. 按序打印

给你一个类:

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<semaphore.h>


信号量的数据类型为结构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);
}
相关文章
|
1月前
|
算法 Java 大数据
Java多线程中顺序打印
Java多线程中顺序打印
27 2
Java多线程中顺序打印
|
8月前
高频面试题:如何分别用三种姿势实现三个线程交替打印0到100
高频面试题:如何分别用三种姿势实现三个线程交替打印0到100
190 0
|
2月前
|
存储 索引 Python
leetcode-387:字符串中的第一个唯一字符(队列以及堆栈最简单的实现方式)
leetcode-387:字符串中的第一个唯一字符(队列以及堆栈最简单的实现方式)
36 1
【多线程】两个线程轮流打印数字1-100,一个打奇数一个打偶数,顺序打印
【多线程】两个线程轮流打印数字1-100,一个打奇数一个打偶数,顺序打印
|
8月前
死循环记录
死循环记录
54 0
|
11月前
三个线程循环顺序打印
三个线程循环顺序打印
57 0
|
调度
leetcode.1114-按序打印-多线程案例
leetcode.1114-按序打印-多线程案例
83 0
leetcode线程题1116——打印零与奇偶数
leetcode线程题1116——打印零与奇偶数
斐讯面试记录—三线程交替打印ABC
斐讯面试记录—三线程交替打印ABC
51 0
|
运维 Java
面试题精选:两个线程按顺序交替输出1-100
面试题精选:两个线程按顺序交替输出1-100
157 0