Skip to content

Commit 8ad5781

Browse files
committed
技巧:只允许一个线程运行
技巧:只允许一个线程运行。
1 parent 3a9773b commit 8ad5781

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
* [查看线程信息](print-threads.md)
4141
* [在Solaris上使用maintenance命令查看线程信息](maint-info-sol-threads.md)
4242
* [不显示线程启动和退出信息](show-print-thread-events.md)
43+
* [只允许一个线程运行](set-scheduler-locking-on.md)
4344

4445
# core dump文件
4546
* [为调试进程产生core dump文件](generate-core-dump-file.md)

src/set-scheduler-locking-on.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# 只允许一个线程运行
2+
## 例子
3+
#include <stdio.h>
4+
#include <pthread.h>
5+
int a = 0;
6+
int b = 0;
7+
void *thread1_func(void *p_arg)
8+
{
9+
while (1)
10+
{
11+
a++;
12+
sleep(1);
13+
}
14+
}
15+
16+
void *thread2_func(void *p_arg)
17+
{
18+
while (1)
19+
{
20+
b++;
21+
sleep(1);
22+
}
23+
}
24+
25+
int main(void)
26+
{
27+
pthread_t t1, t2;
28+
29+
pthread_create(&t1, NULL, thread1_func, "Thread 1");
30+
pthread_create(&t2, NULL, thread2_func, "Thread 2");
31+
32+
sleep(1000);
33+
return;
34+
}
35+
36+
37+
## 技巧
38+
用gdb调试多线程程序时,一旦程序断住,所有的线程都处于暂停状态。此时当你调试其中一个线程时(比如执行“`step`”,“`next`”命令),所有的线程都会同时执行。以上面程序为例:
39+
40+
(gdb) b a.c:9
41+
Breakpoint 1 at 0x400580: file a.c, line 9.
42+
(gdb) r
43+
Starting program: /data2/home/nanxiao/a
44+
[Thread debugging using libthread_db enabled]
45+
Using host libthread_db library "/lib64/libthread_db.so.1".
46+
[New Thread 0x7ffff782c700 (LWP 17368)]
47+
[Switching to Thread 0x7ffff782c700 (LWP 17368)]
48+
49+
Breakpoint 1, thread1_func (p_arg=0x400718) at a.c:9
50+
9 a++;
51+
(gdb) p b
52+
$1 = 0
53+
(gdb) s
54+
10 sleep(1);
55+
(gdb) s
56+
[New Thread 0x7ffff6e2b700 (LWP 17369)]
57+
11 }
58+
(gdb)
59+
60+
Breakpoint 1, thread1_func (p_arg=0x400718) at a.c:9
61+
9 a++;
62+
(gdb)
63+
10 sleep(1);
64+
(gdb) p b
65+
$2 = 3
66+
67+
`thread1_func`更新全局变量`a`的值,`thread2_func`更新全局变量`b`的值。我在`thread1_func``a++`语句打上断点,当断点第一次命中时,打印`b`的值是`0`,在单步调试`thread1_func`几次后,`b`的值变成`3`,证明在单步调试`thread1_func`时,`thread2_func`也在执行。
68+
如果想在调试一个线程时,让其它线程暂停执行,可以使用“`set scheduler-locking on`”命令:
69+
70+
(gdb) b a.c:9
71+
Breakpoint 1 at 0x400580: file a.c, line 9.
72+
(gdb) r
73+
Starting program: /data2/home/nanxiao/a
74+
[Thread debugging using libthread_db enabled]
75+
Using host libthread_db library "/lib64/libthread_db.so.1".
76+
[New Thread 0x7ffff782c700 (LWP 19783)]
77+
[Switching to Thread 0x7ffff782c700 (LWP 19783)]
78+
79+
Breakpoint 1, thread1_func (p_arg=0x400718) at a.c:9
80+
9 a++;
81+
(gdb) set scheduler-locking on
82+
(gdb) p b
83+
$1 = 0
84+
(gdb) s
85+
10 sleep(1);
86+
(gdb)
87+
11 }
88+
(gdb)
89+
90+
Breakpoint 1, thread1_func (p_arg=0x400718) at a.c:9
91+
9 a++;
92+
(gdb)
93+
10 sleep(1);
94+
(gdb)
95+
11 }
96+
(gdb) p b
97+
$2 = 0
98+
99+
可以看到在单步调试`thread1_func`几次后,`b`的值仍然为`0`,证明在在单步调试`thread1_func`时,`thread2_func`没有执行。
100+
101+
此外,“`set scheduler-locking`”命令除了支持`off``on`模式外(默认是`off`),还有一个`step`模式。含义是:当用"`step`"命令调试线程时,其它线程不会执行,但是用其它命令(比如"`next`")调试线程时,其它线程也许会执行。
102+
103+
这个命令依赖于具体操作系统的调度策略,使用时需注意。参见[gdb手册](https://sourceware.org/gdb/onlinedocs/gdb/All_002dStop-Mode.html#All_002dStop-Mode).
104+
105+
## 贡献者
106+
107+
nanxiao

0 commit comments

Comments
 (0)