标签: busy-waiting

没有print语句,循环看不到其他线程更改的值

在我的代码中,我有一个循环,等待从不同的线程更改某个状态.另一个线程工作,但我的循环永远不会看到更改的值.它永远等待.但是,当我System.out.println在循环中放置一个语句时,它突然起作用了!为什么?


以下是我的代码示例:

class MyHouse {
    boolean pizzaArrived = false;

    void eatPizza() {
        while (pizzaArrived == false) {
            //System.out.println("waiting");
        }

        System.out.println("That was delicious!");
    }

    void deliverPizza() {
        pizzaArrived = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

while循环正在运行时,我deliverPizza()从另一个线程调用来设置pizzaArrived变量.但循环仅在我取消注释System.out.println("waiting");语句时才有效.这是怎么回事?

java multithreading synchronization busy-waiting

85
推荐指数
1
解决办法
6588
查看次数

Spinlock与忙碌的等待

请解释为什么忙碌等待通常不赞成,而旋转通常被认为是好的.据我所知,它们都无限循环,直到满足某些条件.

spinlock busy-waiting

14
推荐指数
1
解决办法
6265
查看次数

忙等待和轮询有什么区别?

来自维基百科关于投票的文章

计算机科学中的轮询或轮询操作是指客户端程序将外部设备的状态作为同步活动进行主动采样.轮询最常用于输入/输出(I/O),也称为轮询I/O或软件驱动的I/O.

轮询有时与忙等待轮询(忙等待)同义.在这种情况下,当需要I/O操作时,计算机除了检查I/O设备的状态之外什么都不做,直到它准备就绪,此时访问设备.换句话说,计算机等待设备准备就绪.
轮询还指的是重复检查设备是否准备就绪的情况,如果不是,则计算机返回到不同的任务.尽管不像繁忙等待那样浪费CPU周期,但这通常不如轮询,中断驱动I/O的替代方案那样有效.

因此,当一个线程不使用"条件变量"时,它会被称为"轮询"数据更改还是"忙等待"?

multithreading condition-variable polling busy-waiting

10
推荐指数
2
解决办法
2万
查看次数

Haskell:监控文件而不进行轮询(在linux中使用inotify)

是否有haskell库函数来监视文件而不进行轮询?

通过民意调查我会做这样的事情:

monitor file mtime handler = do
    threadDelay n -- sleep `n` ns
    t <- getModificationTime file
    if t > mtime
        then handler >> monitor file t handler
        else monitor file mtime handler
Run Code Online (Sandbox Code Playgroud)

我想要的是一个阻塞的getModificationTime,它将被系统唤醒.有什么东西可用吗?

如果只有posix系统可用,我会非常高兴,但越便携越好:-)

编辑:我知道 hinotify,但我在Mac上(这就是为什么我提到POSIX).

haskell polling inotify busy-waiting

10
推荐指数
3
解决办法
1828
查看次数

在C中,我们可以在没有忙碌的情况下从管道中读取,可能正在使用回调或其他方式吗?

我试图从分叉过程的STDOUT中读取.但是,如果我正在无限地从管道读取,for loop即使没有数据通过管道也会忙着等待(如果我错了请纠正我),我想必须有更好的方法来做其他事情比使用sleep,如果它是短的间隔,可能是回调,这我不知道.以下是我尝试过的代码片段.

pid_t pid = fork();  
switch (pid) {
    case 0:
        dup2 (pipes[1], STDOUT_FILENO );
        dup2(pipes[1], STDERR_FILENO); 
        close(pipes[0]); 
        close(pipes[1]);
        execv(path, args);
        break;
    default :
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        child_pid = pid;
        signal(SIGHUP, mysighandle);
        close(pipes[1]); 
        ssize_t nbytes;
        for (;;) {
            nbytes = read(pipes[0], buf, BUFSIZE); 
            if (nbytes == -1){
                break;
            }
            if (nbytes == 0) {
                break;
            }
            syslog(LOG_NOTICE, "%s", buf);
Run Code Online (Sandbox Code Playgroud)

有人可以建议一个没有忙碌的更好的方法,可以用来从管道读取数据吗?由于我是初学者C,所以对代码片段的任何引用都很受欢迎.

问候.

c pipe busy-waiting

10
推荐指数
1
解决办法
557
查看次数

为什么ScheduledExecutorService.shutdown()使用100%的CPU?

我有以下简单的代码:

package main;

import java.util.concurrent.*;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        new Main();
    }

    public Main() throws InterruptedException {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        executor.schedule(new MyRunnable(), 10, TimeUnit.SECONDS);
        System.out.println("Shutting down...");
        executor.shutdown();
        System.out.println("Awaiting termination...");
        executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
        System.out.println("Main finished!");
    }

    private class MyRunnable implements Runnable {
        public void run() {
            System.out.println("Finished running!");
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

实际上,虽然我的真实代码比这更复杂,但我可以在这些方面隔离问题.代码基本上等待10秒运行runnable,然后通知主程序的结束.

但是,我注意到了10秒钟,我的核心之一用于100%.

如果我评论这一行:

executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
Run Code Online (Sandbox Code Playgroud)

cpu核心也以100%使用,主程序也在Runnable之前完成.

如果我评论这一行:

executor.shutdown();
Run Code Online (Sandbox Code Playgroud)

cpu已正确使用但程序无法完成.

如果我评论前两行,则cpu正确使用但主程序无法完成.

  1. 我的代码有问题吗?
  2. 正在executor.shutdown(); 做某种忙碌的等待而不是仅仅禁用提交新任务?
  3. 或者我应该责怪JVM?

附加细节:

$ java -version
java version "1.6.0_26" …
Run Code Online (Sandbox Code Playgroud)

java linux concurrency executor busy-waiting

9
推荐指数
1
解决办法
4170
查看次数

防止MPI忙于循环

我有一个MPI程序,它过度订阅/过度使用其处理器.那就是:进程多于处理器.

但是,在给定时间内,这些进程中只有少数是活动的,因此不应该争用计算资源.

但是,就像来自海底总动员的一群海鸥一样,当这些过程等待通信时,他们都在忙着循环,问"我的?我的?我的?"?

                                      Nemo Seagulls

我正在使用英特尔MPI和OpenMPI(适用于不同的机器).我怎样才能说服他们没有繁忙的循环?

我的快速而肮脏的解决方案是MPI_Iprobe在带有sleep命令的循环中使用(参见此处).

c++ mpi openmpi intel-mpi busy-waiting

8
推荐指数
1
解决办法
636
查看次数

为什么允许编译器优化这个繁忙的等待循环?

#include <iostream>
#include <thread>
#include <mutex>

int main()
{
    std::atomic<bool> ready = false;

    std::thread threadB = std::thread([&]() {
        while (!ready) {}

        printf("Hello from B\n");
    });

    std::this_thread::sleep_for(std::chrono::seconds(1));

    printf("Hello from A\n");

    ready = true;

    threadB.join();

    printf("Hello again from A\n");
}
Run Code Online (Sandbox Code Playgroud)

这是 CppCon 演讲中的一个例子https://www.youtube.com/watch?v=F6Ipn7gCOsY&ab_channel=CppCon(17分钟)

目标是先打印Hello from A然后允许threadB开始。很明显,应该避免忙等待,因为它使用了大量的 CPU。

作者说while (!ready) {}循环可以ready由编译器优化(通过将 的值放入寄存器),因为编译器看到threadB从不睡觉所以ready永远不会改变。但是即使线程从不休眠,另一个线程仍然可以更改该值,对吗?没有数据竞争,因为它ready是原子的。作者声明这个代码是UB。有人可以解释为什么允许编译器进行这样的优化吗?

c++ multithreading compiler-optimization busy-waiting

7
推荐指数
1
解决办法
153
查看次数

高吞吐量非阻塞服务器设计:繁忙等待的替代方案

我一直在为多媒体消息构建一个高吞吐量的服务器应用程序,实现语言是C++。每台服务器可以独立使用,也可以将多台服务器连接在一起,创建一个基于DHT的覆盖网络;服务器就像Skype一样的超级对等点。

工作正在进行中。目前,服务器每秒可以处理大约 200,000 条消息(256 字节消息),并且在我的机器(Intel i3 Mobile 2 GHz、Fedora Core 18(64 位)、4 GB RAM)上的最大吞吐量约为 256 MB/s长度为 4096 字节的消息。服务器有两个线程,一个线程用于处理所有 IO(基于 epoll,边缘触发),另一个线程用于处理传入的消息。覆盖管理还有另一个线程,但在当前的讨论中无关紧要。

讨论中的两个线程使用两个循环缓冲区共享数据。线程编号 1 使用一个循环缓冲区为线程编号 2 的新消息入队,而线程编号 2 通过另一个循环缓冲区返回已处理的消息。服务器是完全无锁的。我没有使用任何同步原语,甚至没有使用原子操作。

循环缓冲区永远不会溢出,因为消息是池化的(在启动时预先分配)。事实上,所有重要/经常使用的数据结构都被集中起来以减少内存碎片并提高缓存效率,因此我们知道服务器启动时我们将创建的最大消息数,因此我们可以预先计算最大缓冲区的大小,然后相应地初始化循环缓冲区。

现在我的问题是:线程 #1 将序列化消息一次一条消息(实际上是指向消息对象的指针)排入队列,而线程 #2 以块(32/64/128 的块)从队列中取出消息,然后返回通过第二个循环缓冲区以块的形式处理消息。如果没有新消息,线程#2 会一直忙着等待,因此让 CPU 核心之一一直忙着。我怎样才能进一步改进设计?忙等待策略的替代方案是什么?我想优雅而有效地做到这一点。我考虑过使用信号量,但我担心这不是最好的解决方案,原因很简单,每次我在线程 #1 中排队消息时都必须调用“sem_post”,这可能会大大降低吞吐量,第二个线程必须调用“sem_post”等于防止信号量溢出的次数。另外我担心信号量实现可能在内部使用互斥锁。

第二个不错的选择可能是使用信号,如果我能发现一种算法,仅当第二个线程“清空队列并且正在调用 sigwait”或“已经在等待 sigwait”,简而言之信号必须提高最少次数,尽管如果信号比需要的次数多几次也不会受到伤害。是的,我确实使用过谷歌搜索,但我在互联网上找到的解决方案都不是令人满意的。以下是一些注意事项:

A. 服务器在进行系统调用时必须浪费最少的 CPU 周期,并且必须使用最少的系统调用次数。

B. 必须有非常低的开销并且算法必须是高效的。

C. 没有任何锁定。

我希望所有选项都摆在桌面上。

这是我共享服务器信息的站点的链接,以便更好地了解其功能和目的:www.wanhive.com

c++ algorithm multithreading producer-consumer busy-waiting

5
推荐指数
1
解决办法
1815
查看次数

主题:忙等待 - 空的 While 循环

在大学的课程中,我们学习Threads并使用了“忙等待”方法作为CarTrafficLight. 对于这个任务,我们构建了三个类:

  • TrafficLight (implements Runnable)
  • Car (implements Runnable)
  • Main

在我们的Main班级中,我们开始了两个Threads,一个是Car,一个是TrafficLight。在Car具有布尔属性hasToWaitrun()此类中的方法的工作方式是,while只要hasToWait == true. 为了改变这一点,我们notifyCar()Car类中有一个方法,它被TrafficLight. 中的run()方法TrafficLight通过aThread.sleep()来模拟一定的等待时间。

在我的教授那里一切正常,但最终我遇到了严重的问题。只要类中的while循环Car为空。当我把一个System.out.println()-这是不是空的,它的工作原理。但如果Syso 为空,则结果是不显示方法的Text Run。当Thread.sleep()inTrafficLight0. 比它适用于空while循环。

这是我的代码:

汽车.java:

package trafficlight;

public class Car implements Runnable …
Run Code Online (Sandbox Code Playgroud)

java eclipse multithreading busy-waiting

5
推荐指数
1
解决办法
1万
查看次数