Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
Xcode 有没有办法找到拥有锁的线程?_Xcode_Multithreading_Semaphore_Lldb - Fatal编程技术网

Xcode 有没有办法找到拥有锁的线程?

Xcode 有没有办法找到拥有锁的线程?,xcode,multithreading,semaphore,lldb,Xcode,Multithreading,Semaphore,Lldb,我遇到了这样的情况,我有数百个线程睡在同一个锁上。我想找到一种有效的方法来停止调试器中的程序,并找到当前拥有锁的线程 我已经尝试过手动检查每个线程的堆栈回溯,但这是一个极其繁琐的过程,而且大多数时候我要么错过了,要么无法识别未被阻塞的线程 这些锁目前是os_不公平的_锁,但这个问题也适用于NSLock 我有一个想法,我可能会添加一些调试代码,在线程获得锁后,它可以将其线程ID存储在全局变量中。当我停止应用程序时,我可以检查该全局线程以帮助我找到锁所有者的线程。我的问题似乎是我无法获得Xcode使

我遇到了这样的情况,我有数百个线程睡在同一个锁上。我想找到一种有效的方法来停止调试器中的程序,并找到当前拥有锁的线程

我已经尝试过手动检查每个线程的堆栈回溯,但这是一个极其繁琐的过程,而且大多数时候我要么错过了,要么无法识别未被阻塞的线程

这些锁目前是os_不公平的_锁,但这个问题也适用于NSLock

我有一个想法,我可能会添加一些调试代码,在线程获得锁后,它可以将其线程ID存储在全局变量中。当我停止应用程序时,我可以检查该全局线程以帮助我找到锁所有者的线程。我的问题似乎是我无法获得Xcode使用的线程编号。通过pthread_threadid_np获得的线程ID似乎与Xcode线程列表中的任何编号都不对应


解决方案?思想?想法?

不是理想的解决方案,但通过修改我的代码以捕获上次获得锁的线程的线程ID(如问题所述),可以使用lldb的线程列表命令确定线程

添加代码以获取当前线程的ID,类似于:

static UInt64 DevCurrentThreadID( void )
{
    pthread_t thread = pthread_self();
    UInt64 threadID;
    pthread_threadid_np(thread, &threadID);
    return threadID;
}
获得锁后,将胎面ID保存在全局变量中

在Xcode中停止后,切换到lldb控制台窗格并发出命令

threads list
它将列出线程以及每个线程的ID tid:

  thread #1: tid = 0x4722c, 0x00007fff6eaef22a libsystem_kernel.dylib`mach_msg_trap + 10, queue = 'com.apple.main-thread'
* thread #4: tid = 0x47393, 0x00000001000b7ade StatsHelper`DevCurrentThreadID at PackageSource+RecordBlaster.m:86:9, name = 'verify', stop reason = breakpoint 16.1
  thread #236: tid = 0x479fe, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #412: tid = 0x47d7f, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #437: tid = 0x47eef, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #450: tid = 0x47f0d, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #451: tid = 0x47f43, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #452: tid = 0x47f44, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #453: tid = 0x47f45, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #454: tid = 0x47f46, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #455: tid = 0x47f47, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #456: tid = 0x47f48, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #457: tid = 0x47f49, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
... and so on

获取全局变量中的值,将其转换为十六进制,然后在输出中搜索匹配的tid=0x。这就是拥有锁的线程。

不是理想的解决方案,但是通过修改我的代码以捕获上次获得锁的线程的线程ID(如问题中所述),可以使用lldb的thread list命令确定线程

添加代码以获取当前线程的ID,类似于:

static UInt64 DevCurrentThreadID( void )
{
    pthread_t thread = pthread_self();
    UInt64 threadID;
    pthread_threadid_np(thread, &threadID);
    return threadID;
}
获得锁后,将胎面ID保存在全局变量中

在Xcode中停止后,切换到lldb控制台窗格并发出命令

threads list
它将列出线程以及每个线程的ID tid:

  thread #1: tid = 0x4722c, 0x00007fff6eaef22a libsystem_kernel.dylib`mach_msg_trap + 10, queue = 'com.apple.main-thread'
* thread #4: tid = 0x47393, 0x00000001000b7ade StatsHelper`DevCurrentThreadID at PackageSource+RecordBlaster.m:86:9, name = 'verify', stop reason = breakpoint 16.1
  thread #236: tid = 0x479fe, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #412: tid = 0x47d7f, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #437: tid = 0x47eef, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #450: tid = 0x47f0d, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #451: tid = 0x47f43, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #452: tid = 0x47f44, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #453: tid = 0x47f45, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #454: tid = 0x47f46, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #455: tid = 0x47f47, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #456: tid = 0x47f48, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #457: tid = 0x47f49, 0x00007fff6eaf0bfe libsystem_kernel.dylib`__workq_kernreturn + 10
... and so on

获取全局变量中的值,将其转换为十六进制,然后在输出中搜索匹配的tid=0x。这就是拥有锁的线程。

看起来您已经找到了所需的内容,但只是为了让所有内容都清晰明了:

达尔文实际上使用了三种不同的线程ID。每个线程都有一个由pthread_self报告的pthread id、一个由mach_thread_self报告的mach thread端口,以及一个全局唯一的线程id,其中包括通过调用pthread_threadid_np来填充。后者是所有其他系统服务(如样本、spindump、仪器等)的显示。这也是lldb打印的。这就是你在答案中所匹配的

注意,您不需要手动查看线程列表就可以找到您的线程。您可以使用Python API。例如,如果知道要查找的线程ID是0x16cc5,则可以执行以下操作:

(lldb) script lldb.process.SetSelectedThreadByID(0x16cc5)
这会将所选线程设置为该线程,以便bt和其他命令对其进行操作。它还将此设置为Xcode中的选定线程

注意,在lldb的命令集中可能应该有一个thread select-thread id

如果要在找到线程时进行更多工作,可以执行以下操作:

(lldb) script
>>> for thread in lldb.process.threads:
...     if thread.GetThreadID() == 0x16cc5:
...         # Add code here
... 
您甚至可以让Python获取全局变量并将其用于比较。如果你真的有雄心壮志,你可以把它变成一个自定义的lldb命令,以便更方便地使用

您可以在此处阅读有关lldb Python API的更多信息:

API文档如下所示:


看起来你已经找到了你需要的东西,但只是为了让一切都清晰明了:

达尔文实际上使用了三种不同的线程ID。每个线程都有一个由pthread_self报告的pthread id、一个由mach_thread_self报告的mach thread端口,以及一个全局唯一的线程id,其中包括通过调用pthread_threadid_np来填充。后者是所有其他系统服务(如样本、spindump、仪器等)的显示。这也是lldb打印的。这就是你在答案中所匹配的

注意,您不需要手动查看线程列表就可以找到您的线程。您可以使用Python API。例如,如果知道要查找的线程ID是0x16cc5,则可以执行以下操作:

(lldb) script lldb.process.SetSelectedThreadByID(0x16cc5)
这会将所选线程设置为该线程,以便bt和其他命令对其进行操作。它还将此设置为Xcode中的选定线程

注意,在lldb的命令集中可能应该有一个thread select-thread id

如果要在找到线程时进行更多工作,可以执行以下操作:

(lldb) script
>>> for thread in lldb.process.threads:
...     if thread.GetThreadID() == 0x16cc5:
...         # Add code here
... 
您甚至可以让Python获取全局变量并将其用于比较。如果你真的有雄心壮志,你可以把它变成一个定制的工具 db命令更方便的使用

您可以在此处阅读有关lldb Python API的更多信息:

API文档如下所示:


避免锁?:我有一半厚脸皮,但只有一半。我认为这是GCD和串行线程应该让我们做的。这是真正的高性能代码,GCD太慢了。我有一个位图集合,它从并发队列上运行的多个线程中更新,更新操作是:锁定、索引、测试、按位或/和、解锁、返回。这些操作执行了数亿次,GCD队列太慢,至少慢了一个数量级。测试分为两个步骤,所以我不能使用原子变量来解决这个问题。我还没有检查,但是Xcode的线程ID是否对应于给定线程的pthread_self值?或者,也许是pthread\u mach\u thread\u np?如果使用pthread\u setname\u np设置线程名称,Xcode是否会显示该名称?最后,我要说的是,拥有数百个线程不太可能有任何性能优势。“你只是给管理它们带来了更多的开销。”肯特霍马斯,它们似乎没有关系。在Xcode中停止我的应用程序,调试器显示我在线程4中,pthread_self返回0x70000db7b000,pthread_threadid_np返回183335。因此,我不确定这些数字与Xcode的线程数有什么关系。至于数百个线程的性能问题,我并不担心性能,因为我想验证一些东西没有卡在某个地方。存在会导致所有处理线程阻塞的定期维护任务。我只是想确定这是因为这些任务,而不是其他意外事件导致所有线程阻塞。是否避免锁定?:我有一半厚脸皮,但只有一半。我认为这是GCD和串行线程应该让我们做的。这是真正的高性能代码,GCD太慢了。我有一个位图集合,它从并发队列上运行的多个线程中更新,更新操作是:锁定、索引、测试、按位或/和、解锁、返回。这些操作执行了数亿次,GCD队列太慢,至少慢了一个数量级。测试分为两个步骤,所以我不能使用原子变量来解决这个问题。我还没有检查,但是Xcode的线程ID是否对应于给定线程的pthread_self值?或者,也许是pthread\u mach\u thread\u np?如果使用pthread\u setname\u np设置线程名称,Xcode是否会显示该名称?最后,我要说的是,拥有数百个线程不太可能有任何性能优势。“你只是给管理它们带来了更多的开销。”肯特霍马斯,它们似乎没有关系。在Xcode中停止我的应用程序,调试器显示我在线程4中,pthread_self返回0x70000db7b000,pthread_threadid_np返回183335。因此,我不确定这些数字与Xcode的线程数有什么关系。至于数百个线程的性能问题,我并不担心性能,因为我想验证一些东西没有卡在某个地方。存在会导致所有处理线程阻塞的定期维护任务。我只是想确定这是因为这些任务,而不是其他意外的事情导致所有线程阻塞。非常感谢您提供的详细信息。我知道调试器蕴藏着巨大的力量,如果我花点时间从编写代码和修复bug中学习它,我会过得更好;非常感谢您提供的详细信息。我知道调试器蕴藏着巨大的力量,如果我花点时间从编写代码和修复bug中学习它,我会过得更好;