Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 您能否在DTrace中以多CPU安全的方式比较探测器之间的值?_Macos_Dtrace - Fatal编程技术网

Macos 您能否在DTrace中以多CPU安全的方式比较探测器之间的值?

Macos 您能否在DTrace中以多CPU安全的方式比较探测器之间的值?,macos,dtrace,Macos,Dtrace,我正在尝试编写一个DTrace脚本,它执行以下操作: 每当新线程启动时,递增一个计数 每当其中一个线程退出时,减小计数,如果计数现在为零,则退出脚本 我有这样的想法: BEGIN { threads_alive = 0; } proc:::lwp-start /execname == $$1/ { self->started = timestamp; threads_alive += 1; } proc:::lwp-exit /self->started/ { t

我正在尝试编写一个DTrace脚本,它执行以下操作:

  • 每当新线程启动时,递增一个计数
  • 每当其中一个线程退出时,减小计数,如果计数现在为零,则退出脚本
  • 我有这样的想法:

    BEGIN {
      threads_alive = 0;
    }
    
    proc:::lwp-start /execname == $$1/ {
      self->started = timestamp;
      threads_alive += 1;
    }
    
    proc:::lwp-exit /self->started/ {
      threads_alive -= 1;
      if (threads_alive == 0) {
        exit(0);
      }
    }
    
    但是,这不起作用,因为
    threads\u alive
    是一个标量变量,因此它不是多cpu安全的。因此,多个线程将覆盖彼此对变量的更改

    我还尝试使用聚合变量:

    @thread_count = sum(1)
    //or
    @threads_entered = count();
    @threads_exitted = count();
    

    不幸的是,我还没有发现语法能够像
    @thread\u count==0
    @threads\u start==@threads\u stopped
    DTrace没有实现您建议的线程安全数据共享的功能,但是您有一些选项,具体取决于您尝试执行的操作

    如果可执行文件名是唯一的,则可以分别使用
    proc:::start
    proc:::exit
    探测第一个线程的开始和最后一个线程的退出:

    proc:::start
    /execname == $$1/
    {
            my_pid = pid;
    }
    
    proc:::exit
    /pid == my_pid/
    {
            exit(0);
    }
    
    如果您正在使用
    -c
    选项来
    dtrace
    ,则
    BEGIN
    探测会在相应的
    proc:::start
    后很快触发。在内部,
    dtrace-c
    启动指定的fork和指定的命令,然后在以下四点之一开始跟踪:
    exec
    (在新程序的第一条指令之前)、
    preinit
    (在ld加载所有库之后)、
    postinit
    (在每个库的
    \u init
    运行之后),或
    main
    (就在程序的
    main
    功能的第一条指令之前,尽管macOS不支持该功能)

    如果使用
    dtrace-x evaltime=exec-c
    BEGIN
    将在程序的第一条指令执行之前立即触发:

    # dtrace -xevaltime=exec -c /usr/bin/true -n 'BEGIN{ts = timestamp}' -n 'pid$target:::entry{printf("%dus", (timestamp - ts)/1000); exit(0); }'
    dtrace: description 'BEGIN' matched 1 probe
    dtrace: description 'pid$target:::entry' matched 1767 probes
    dtrace: pid 1848 has exited
    CPU     ID                    FUNCTION:NAME
     10  16757                _dyld_start:entry 285us
    

    285us是由于在macOS上通过
    /proc
    ptrace(2)
    恢复过程所需的时间。您可以使用
    BEGIN
    pid$target::\u dyld\u start:entry
    ,而不是
    proc:::start
    pid$target::main:entry

    DTrace没有实现此处建议的线程安全数据共享的功能。你能提供一点关于你想做什么的背景吗?
    proc:exit/execname=$$1/{exit(0)}
    是否有效?
    -c
    -p
    选项是否已经满足了您的要求?@ahl谢谢,这很有意义。我希望在进程启动之前有dtrace start,这样它就可以捕获该进程的lwp启动探测(至少在MacOS上使用
    -c
    时似乎不会发生这种情况)。然后我开始这个过程,观察它直到结束,在这一点上我希望dtrace退出。似乎proc:::exit可以工作,只要我不多次运行该进程(我不打算这么做)。如果你愿意,写下来作为答案,我会接受,或者我会写一个答案。