可以捕获操作系统在线程上进行上下文切换吗?

发布于 2024-12-20 05:03:00 字数 123 浏览 1 评论 0原文

我想知道如何捕获 java 中被上下文切换中断的线程。 我有两个线程并排运行,它们都向上和向下更改相同的 int,为了我的报告,我想知道如何捕获开关并执行某些操作。 (例如,发生这种情况时制作一个简单的 System.out)谢谢!

I would like to know how to catch a thread being interrupted by a Context Switch in java.
I got two threads running side by side, which are both changing the same int up and down, and I would like for the sake of my report, to know how to catch the switches, and do something. (eg. make a simple System.out when that happens) Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

素罗衫 2024-12-27 05:03:00

就应用程序而言,上下文切换是不可见的 - 没有信号或消息发送到应用程序通知它的应用程序。

唯一可能提示申请的是时间。例如,如果您重复对紧密循环进行计时,您可能能够(不可靠地)检测到执行循环时发生的上下文切换,因为与之前的执行相比,所需的时间更长。没有被打扰。不幸的是,这仅适用于像 C 这样的编译语言。像 Java 这样使用虚拟机的语言实际上不可能可靠地检测到这样的事情,因为循环减慢可能归因于多种原因,例如垃圾收集器发挥作用。

此外,请记住,任何系统调用(尤其是 I/O 调用(例如用于记录此类事件的调用))通常会导致隐式上下文切换,这可能会导致您想做的任何事情都失败。

无论如何,你为什么想知道这样的事情呢?尤其是来自 Java 应用程序?

编辑:

好吧,如果您在创建同步问题之后,这是我的版本:

public class Test {
    public static long count = 0;

    public static void main(String[] args) {
        for (int run = 0; run < 5; ++run) {
            Test.count = 0;

            Thread[] threads = new Thread[10];

            for (int i = 0; i < threads.length; ++i) {
                threads[i] = new Thread(new Runnable() {
                    public void run() {
                        for (long i = 0; i < (10 * 1000 * 1000 * 1000); ++i) {
                            Test.count += 1;
                        }
                    }
                });
            }

            for (int i = 0; i < threads.length; ++i) {
                threads[i].start();
            }

            for (int i = 0; i < threads.length; ++i) {
                try {
                    threads[i].join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println(Test.count);
        }
    }
}

这是我从单次运行中得到的结果:

1443685504
1439908180
1461384255
1477413204
1440892041

As far as an application is concerned context switches are invisible - there is no signal or message sent to the application that notifies it.

The only thing that might tip off an application is timing. For example, if you time a tight loop repeatedly, you might be able to (unreliably) detect a context switch that happens as the loop is executed, due to the longer time required in comparison to executions that were not interrupted. Unfortunately, this would only be possible for compiled languages like C. Languages like Java that make use of a virtual machine make it practically impossible to reliably detect something like this because a loop slowing down might be attributed to any number of reasons, like e.g. the garbage collector acting up.

Moreover, keep in mind that any system call - and especially I/O calls like the ones you'd use to log such an event - very often cause an implicit context switch, which could throw off anything you might want to do.

Why would you want to know something like this anyway? And especially from a Java application?

EDIT:

Well, if you are after creating a synchronization problem, here's my version:

public class Test {
    public static long count = 0;

    public static void main(String[] args) {
        for (int run = 0; run < 5; ++run) {
            Test.count = 0;

            Thread[] threads = new Thread[10];

            for (int i = 0; i < threads.length; ++i) {
                threads[i] = new Thread(new Runnable() {
                    public void run() {
                        for (long i = 0; i < (10 * 1000 * 1000 * 1000); ++i) {
                            Test.count += 1;
                        }
                    }
                });
            }

            for (int i = 0; i < threads.length; ++i) {
                threads[i].start();
            }

            for (int i = 0; i < threads.length; ++i) {
                try {
                    threads[i].join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println(Test.count);
        }
    }
}

Here's what I got from a single run:

1443685504
1439908180
1461384255
1477413204
1440892041
蒗幽 2024-12-27 05:03:00

记录进行修改的线程。

每次修改int时,存储进行修改的线程。当它与之前的线程不同时,请创建您的 System.out。

否则,您将需要一个允许您中断上下文切换的操作系统。我不知道有哪个操作系统可以让你这样做。

Record the thread making the modification.

Every time the int is modified, store the thread that makes the modification. When it differs from the previous thread, make your System.out.

Otherwise, you would need an operating system that allows you to interrupt a context switch. I don't know of an operating system that allows you to do that.

挽清梦 2024-12-27 05:03:00

我不认为你可以监听来自线程调度程序(操作系统核心的一部分)的事件,但你可以使用拉策略:

  1. 制作一些静态易失性字符串字段
    • 在每个线程中读取此字段(非常频繁)
    • 如果字段值 != "current-thread-name" =>; print "上下文已切换到 "+线程名称
    • 将线程名称写入字段

I don't think you can listen events from thread scheduler (part ot OS Core) but you can use pull strategy:

  1. Make some static volatile string field
    • In every thread read this field(very often)
    • If field value != "current-thread-name" => print "Context is Switched to "+thread-name
    • write thread name to field
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文