多线程场景下线程退出差异
thread exit discrepency in multi-thread scenario
我写了一个很简单的练习信号量的代码。任务是卖票,每个线程都应该更新总票数的共享变量,直到它变为零。我观察到的问题是 - 出售最后一张票并通过递减它使 ticket_count = 0 的线程退出而不打印它售出的票总数。我在 printf 周围添加了互斥锁,只是为了破解它,因为我在 SO 上阅读了多线程环境中的 printf 问题。我发现这个问题不同于关于多线程的 SO 所指出的正常 printf 问题的原因是 - 它总是(不总是 8/10 次 - 问题是间歇性的 - 其他 2 次它打印所有 4 个线程售票)最后一个线程即售出最后一张票的人跳过 printf 并退出。有人可以指出我做错了什么吗?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <stdbool.h>
#include <unistd.h>
#define NUMTHREADS 4 /* number of threads i.e. ticket sellers */
static unsigned int ticket_count = 25;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
sem_t mutex;
void *ticketProcessing(void *arg)
{
bool loop_alive = true;
int local_counter = 0;
while(loop_alive)
{
sleep(1);
sem_wait(&mutex);
if (ticket_count > 0)
{
local_counter++;
ticket_count--;
printf(" thread id -- %d - decided to sell 1 ticket \n ", (int)pthread_self());
}
else
{
loop_alive = false;
}
sem_post(&mutex);
}
pthread_mutex_lock(&mutex2);
printf(" ticket sold by thread id -- %d -- is %d \n ", (int)pthread_self(), local_counter);
pthread_mutex_unlock(&mutex2);
// return 0;
}
int main(void)
{
pthread_t sellingTicket;
sem_init(&mutex, 0, 1);
int i;
for(i = 0; i < NUMTHREADS; i++)
{
pthread_create(&sellingTicket, NULL, ticketProcessing, NULL);
}
i = 0;
while(i < NUMTHREADS)
{
pthread_join(sellingTicket, NULL);
i++;
}
printf(" All threads exited !!! \n ");
return 0;
}
编辑:我尝试创建数组并以下面的方式加入并且有效
pthread_t threads[4];
for(i = 0; i < 4; i++)
{
pthread_create(&threads[i], NULL, ticketProcessing, NULL);
}
for(i = 0; i < 4; i++)
{
pthread_join(threads[i], NULL);
}
您的连接循环尝试一遍又一遍地连接最后一个线程,而不是尝试连接创建的每个线程。您需要跟踪线程 ID,以便将它们全部加入。
加入线程后,线程 ID 无效,将其传递给任何 pthread_* 函数都是严重错误。
我写了一个很简单的练习信号量的代码。任务是卖票,每个线程都应该更新总票数的共享变量,直到它变为零。我观察到的问题是 - 出售最后一张票并通过递减它使 ticket_count = 0 的线程退出而不打印它售出的票总数。我在 printf 周围添加了互斥锁,只是为了破解它,因为我在 SO 上阅读了多线程环境中的 printf 问题。我发现这个问题不同于关于多线程的 SO 所指出的正常 printf 问题的原因是 - 它总是(不总是 8/10 次 - 问题是间歇性的 - 其他 2 次它打印所有 4 个线程售票)最后一个线程即售出最后一张票的人跳过 printf 并退出。有人可以指出我做错了什么吗?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <stdbool.h>
#include <unistd.h>
#define NUMTHREADS 4 /* number of threads i.e. ticket sellers */
static unsigned int ticket_count = 25;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
sem_t mutex;
void *ticketProcessing(void *arg)
{
bool loop_alive = true;
int local_counter = 0;
while(loop_alive)
{
sleep(1);
sem_wait(&mutex);
if (ticket_count > 0)
{
local_counter++;
ticket_count--;
printf(" thread id -- %d - decided to sell 1 ticket \n ", (int)pthread_self());
}
else
{
loop_alive = false;
}
sem_post(&mutex);
}
pthread_mutex_lock(&mutex2);
printf(" ticket sold by thread id -- %d -- is %d \n ", (int)pthread_self(), local_counter);
pthread_mutex_unlock(&mutex2);
// return 0;
}
int main(void)
{
pthread_t sellingTicket;
sem_init(&mutex, 0, 1);
int i;
for(i = 0; i < NUMTHREADS; i++)
{
pthread_create(&sellingTicket, NULL, ticketProcessing, NULL);
}
i = 0;
while(i < NUMTHREADS)
{
pthread_join(sellingTicket, NULL);
i++;
}
printf(" All threads exited !!! \n ");
return 0;
}
编辑:我尝试创建数组并以下面的方式加入并且有效
pthread_t threads[4];
for(i = 0; i < 4; i++)
{
pthread_create(&threads[i], NULL, ticketProcessing, NULL);
}
for(i = 0; i < 4; i++)
{
pthread_join(threads[i], NULL);
}
您的连接循环尝试一遍又一遍地连接最后一个线程,而不是尝试连接创建的每个线程。您需要跟踪线程 ID,以便将它们全部加入。
加入线程后,线程 ID 无效,将其传递给任何 pthread_* 函数都是严重错误。