这是我的第一个 pthread 程序,我不知道为什么 printf 语句在子线程中打印两次:
int x = 1;
void *func(void *p)
{
x = x + 1;
printf("tid %ld: x is %d\n", pthread_self(), x);
return NULL;
}
int main(void)
{
pthread_t tid;
pthread_create(&tid, NULL, func, NULL);
printf("main thread: %ld\n", pthread_self());
func(NULL);
}
在我的平台(Linux 3.2.0-32-generic #51-Ubuntu SMP x86_64 GNU/Linux)上观察到的输出:
1.
main thread: 140144423188224
tid 140144423188224: x is 2
2.
main thread: 140144423188224
tid 140144423188224: x is 3
3.
main thread: 139716926285568
tid 139716926285568: x is 2
tid 139716918028032: x is 3
tid 139716918028032: x is 3
4.
main thread: 139923881056000
tid 139923881056000: x is 3
tid 139923872798464tid 139923872798464: x is 2
对于 3,来自子线程的两条输出线
对于 4,与 3 相同,甚至输出也是交错的。
线程通常通过时分复用发生。处理器在两个线程之间均匀切换通常效率较低,因为这需要更多的努力和更高的上下文切换。通常,您会发现线程在切换之前会执行多次(如示例 3 和 4 的情况)。子线程在最终终止之前会执行多次(因为主线程已退出)。
示例2:我不知道为什么子线程增加了x而没有输出。
考虑一下这一点。主线程执行。它调用 pthread 并创建一个新线程。新的子线程递增 x。在子线程能够完成 printf 语句之前,主线程启动。突然它也增加了 x。然而,主线程也能够运行 printf 语句。突然 x 现在等于 3。
主线程现在终止(也导致子线程 3 退出)。
这很可能就是您的案例中发生的情况,例如示例 2。
示例 3 清楚地表明变量 x 由于低效锁定和堆栈数据损坏而已损坏!
有关什么是线程的更多信息。
链接 1 - 有关线程的其他信息
链接 2 - 有关线程的附加信息
您还会发现,因为您使用的是 x 的全局变量,所以对该变量的访问在线程之间共享。这很糟糕。非常非常糟糕,因为访问同一变量的线程会由于变量 x 的同一寄存器上发生多次读写而创建竞争条件和数据损坏。
正是由于这个原因,使用互斥锁本质上是在更新变量时创建一个锁,以防止多个线程同时尝试修改同一变量。
互斥锁将确保 x 按顺序更新,而不是像您的情况那样偶尔更新。
有关常规和互斥锁示例中的 Pthreads 的更多信息,请参阅此链接。
Pthreads 和互斥变量
Cheers,
Peter
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)