这是一个面试问题,任何帮助将不胜感激

你如何同步两个线程,其中一个增加一个值,另一个显示它(P.S.显示该值的线程必须只在它是一个新值时才显示一个值)

例如:int x = 5;T1 : 增加到 6
T2 : 必须显示 6(只显示一次),当它变成 7 时必须再次显示

我回答说我会使用类似以下的信号量:

int c=0; // variable that I used to synchronize

// In T1
if( c = 0 )
{
   c++;
   x++; // value that is incremented
}

// in T2
if( c == 1 )
{
   cout<<x;
   c--;
}

然后他问如果在将 c 设置为 1 之后但在增加 x 之前有从线程 T1T2 的上下文切换,你会怎么做(因为在这种情况下它会在增加 x 之前进入 P2 )

这部分我答不上来。任何帮助,将不胜感激。

最佳答案

不错的运动。

您尚未在问题中指定 c++ 标签,但问题本身包含 cout<<x ,因此您可能正在面试 C++ 职位。尽管如此,我还是会用 Java 来回答,因为这是一个面试问题,只要我避免使用任何对 Java 太特定的东西,语言就不会有太大影响。

正如你的面试官所指出的,同步必须在两个方向发生:

  • 打印线程必须等待递增线程完成其工作
  • 递增线程必须等待打印线程完成其工作

  • 所以我们需要一些东西让我们知道打印机已经完成(这样增量器可以运行),另一个让我们知道增量器已经完成。我为此使用了两个信号量:

    Working version on Ideone
    import java.util.concurrent.Semaphore;
    
    class IncrementDemo {
        static int x = 0;
    
        public static void main(String[] args) {
            Semaphore incrementLock = new Semaphore(0);
            Semaphore printLock = new Semaphore(0);
    
            Thread incrementer = new Thread(() -> {
                for(;;) {
                    incrementLock.acquire(); //Wait to be allowed to increment
                    x++;
                    printLock.release(); //Allow the printer to print
                }
            });
    
            Thread printer = new Thread(() -> {
                for (;;) {
                    incrementLock.release(); //Let the incrementer to its job
                    printLock.acquire(); //Wait to be allowed to print
                    System.out.println(x);
                }
            });
    
            incrementer.setDaemon(false); //Keep the program alive after main() exits
            printer.setDaemon(false);
    
            incrementer.start(); //Start both threads
            printer.start();
        }
    
    }
    

    (为了便于阅读,我删除了 acquire 周围的 try/catch 块)。

    输出:
    1
    2
    3
    4
    5
    6
    7
    ...
    

    关于java - 使用信号量的线程同步,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48793791/

    10-11 22:06
    查看更多