C多线程程序行为解释
C multithread program behaviour explanation
int g_ant = 0;
void *writeloop(void *arg)
{
while(g_ant < 10)
{
g_ant++;
usleep(rand()%10);
printf("%d\n", g_ant);
}
exit(0);
}
int main(void)
{
pthread_t time;
pthread_create(&time, NULL, writeloop, NULL);
writeloop(NULL);
pthread_join(time, NUL);
return 0;
}
嗨!我有四个问题,我认为它们属于竞争条件类别......? :-)
- 我想弄清楚为什么 g_ant 在我的计算机上的 printf 在 90% 的情况下从 2 开始并持续到 10,偶尔输出 1、3->10 .我的猜测是因为 usleep 可能会阻碍 thread1 足够长的时间让 thread2 在 thread1 到达 printf 之前递增和 printf。
- 这不会也弄乱 2->10 的数字吗?
- 我也在努力理解 pthread_join 在这个程序中的功能。我的理解是,它是用来等待一个线程完成的。是在等待pthread_create启动的writeloop函数吗?
- writelop(null) 是否被视为第二个线程?
g_ant++;
不是原子操作,这可能导致未定义的行为。你应该使用
pthread_mutex_lock(&mutex);
和
pthread_mutex_unlock(&mutex);
它 90% 次从 2 开始的原因是因为线程 time
进入函数,递增 g_ant
并自行休眠。 OS 倾向于将它从 CPU 中拿走并放在那里另一个没有睡着的线程,在你的情况下是你的主线程,它再次将它增加 1 运行 usleep。现在 g_ant 的值为 2,线程 time
恢复并打印 2 并将其递增到 3。主线程恢复并打印 3 并再次递增它,这会不断切换,这就是为什么你看到数字来自 2 -大多数时候 > 10。
希望它足够清楚并且应该回答 2. 问题。
pthread_join
确保其他线程在您的主线程退出程序之前完成它们的工作。
不,它不被认为是第二个线程,它在主线程上运行函数。
希望对您有所帮助。
- The main thread is considered another thread. The following might help you understand what's going on before you add mutexes (assuming
you have to do that next). Usually, you don't exit() the whole process
from a thread - it would never be joined in the main thread.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int g_ant = 0;
void *writeloop(void *arg)
{
while(g_ant < 10)
{
g_ant++;
usleep( rand() % 10 );
printf("thread: %u global: %d\n", (unsigned int)pthread_self(), g_ant);
}
return NULL;
}
int main(void)
{
pthread_t t;
pthread_create(&t, NULL, writeloop, NULL);
writeloop(NULL);
pthread_join(t, NULL);
printf("Joined\n");
return 0;
}
int g_ant = 0;
void *writeloop(void *arg)
{
while(g_ant < 10)
{
g_ant++;
usleep(rand()%10);
printf("%d\n", g_ant);
}
exit(0);
}
int main(void)
{
pthread_t time;
pthread_create(&time, NULL, writeloop, NULL);
writeloop(NULL);
pthread_join(time, NUL);
return 0;
}
嗨!我有四个问题,我认为它们属于竞争条件类别......? :-)
- 我想弄清楚为什么 g_ant 在我的计算机上的 printf 在 90% 的情况下从 2 开始并持续到 10,偶尔输出 1、3->10 .我的猜测是因为 usleep 可能会阻碍 thread1 足够长的时间让 thread2 在 thread1 到达 printf 之前递增和 printf。
- 这不会也弄乱 2->10 的数字吗?
- 我也在努力理解 pthread_join 在这个程序中的功能。我的理解是,它是用来等待一个线程完成的。是在等待pthread_create启动的writeloop函数吗?
- writelop(null) 是否被视为第二个线程?
g_ant++;
不是原子操作,这可能导致未定义的行为。你应该使用
pthread_mutex_lock(&mutex);
和pthread_mutex_unlock(&mutex);
它 90% 次从 2 开始的原因是因为线程time
进入函数,递增g_ant
并自行休眠。 OS 倾向于将它从 CPU 中拿走并放在那里另一个没有睡着的线程,在你的情况下是你的主线程,它再次将它增加 1 运行 usleep。现在 g_ant 的值为 2,线程time
恢复并打印 2 并将其递增到 3。主线程恢复并打印 3 并再次递增它,这会不断切换,这就是为什么你看到数字来自 2 -大多数时候 > 10。
希望它足够清楚并且应该回答 2. 问题。
pthread_join
确保其他线程在您的主线程退出程序之前完成它们的工作。不,它不被认为是第二个线程,它在主线程上运行函数。
希望对您有所帮助。
- The main thread is considered another thread. The following might help you understand what's going on before you add mutexes (assuming you have to do that next). Usually, you don't exit() the whole process from a thread - it would never be joined in the main thread.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int g_ant = 0;
void *writeloop(void *arg)
{
while(g_ant < 10)
{
g_ant++;
usleep( rand() % 10 );
printf("thread: %u global: %d\n", (unsigned int)pthread_self(), g_ant);
}
return NULL;
}
int main(void)
{
pthread_t t;
pthread_create(&t, NULL, writeloop, NULL);
writeloop(NULL);
pthread_join(t, NULL);
printf("Joined\n");
return 0;
}