注意是否所有线程都在 pthread_cond_wait
Noticing if all threads are at pthread_cond_wait
我目前正在使用 POSIX 库并试用条件变量。
目前我正在使用一个队列来安排任务,如果有一个任务,一个线程使用 pthread_cond_signal 来唤醒一个正在等待 pthread_cond_wait 的线程。
然而,可能有一个点没有创建新任务,所以每个线程都在等待 pthread_cond_wait 并且程序卡在那里。
我是否注意到我的所有线程是否都在等待 pthread_cond_wait?我试过使用计数器和 leave 变量,但我没有让它工作。
我的代码看起来与此处的代码相似:https://code-vault.net/lesson/j62v2novkv:1609958966824
,除了每个线程都在添加新任务(在 executeTask 中)而不是仅在主方法中添加它们。
编辑:
这是我上面网站的代码版本(正在为我加载:/)
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#define THREAD_NUM 4
typedef struct Task
{
int a, b;
} Task;
Task taskQueue[256];
int taskCount = 0;
// THIS VARIABLE IS ADDED
int moreTasks = 10;
pthread_mutex_t mutexQueue;
pthread_cond_t condQueue;
void executeTask(Task *task)
{
usleep(50000);
int result = task->a + task->b;
printf("The sum of %d and %d is %d\n", task->a, task->b, result);
// THIS PART IS ADDED
if (moreTasks > 0)
{
pthread_mutex_lock(&mutexQueue);
moreTasks--;
pthread_mutex_unlock(&mutexQueue);
Task t = {
.a = rand() % 100,
.b = rand() % 100};
submitTask(t);
}
}
void submitTask(Task task)
{
pthread_mutex_lock(&mutexQueue);
taskQueue[taskCount] = task;
taskCount++;
pthread_mutex_unlock(&mutexQueue);
pthread_cond_signal(&condQueue);
}
void *startThread(void *args)
{
while (1)
{
Task task;
pthread_mutex_lock(&mutexQueue);
while (taskCount == 0)
{
pthread_cond_wait(&condQueue, &mutexQueue);
}
task = taskQueue[0];
int i;
for (i = 0; i < taskCount - 1; i++)
{
taskQueue[i] = taskQueue[i + 1];
}
taskCount--;
pthread_mutex_unlock(&mutexQueue);
executeTask(&task);
}
}
int main(int argc, char *argv[])
{
pthread_t th[THREAD_NUM];
pthread_mutex_init(&mutexQueue, NULL);
pthread_cond_init(&condQueue, NULL);
int i;
for (i = 0; i < THREAD_NUM; i++)
{
if (pthread_create(&th[i], NULL, &startThread, NULL) != 0)
{
perror("Failed to create the thread");
}
}
srand(time(NULL));
for (i = 0; i < 100; i++)
{
Task t = {
.a = rand() % 100,
.b = rand() % 100};
submitTask(t);
}
for (i = 0; i < THREAD_NUM; i++)
{
if (pthread_join(th[i], NULL) != 0)
{
perror("Failed to join the thread");
}
}
pthread_mutex_destroy(&mutexQueue);
pthread_cond_destroy(&condQueue);
return 0;
}
我现在的问题是,一段时间后 taskCount 始终为零,因此我的所有线程都在 startThread
方法中的 pthread_cond_wait(&condQueue, &mutexQueue);
。
如果所有线程都在这个地方,我有什么办法注意到吗?如上文所述,如果已经尝试对当前正在等待的线程使用计数器(以及我计算正在工作的线程的版本),但我无法弄清楚如何在每个任务完成后停止所有线程。
如果您想知道有多少线程在等待条件变量,只需在进入等待模式之前增加一个全局计数器并在唤醒时减少它。有了它,您就会知道当前有多少线程正在等待。
例如
//global scope
int num_waiting_threads = 0;
//in function startThread
while (taskCount == 0)
{
//if num_waiting_threads == THREAD_NUM, all threads are waiting
++num_waiting_threads;
pthread_cond_wait(&condQueue, &mutexQueue);
--num_waiting_threads;
}
由于你有固定数量的任务,在处理完每个任务后,每个线程迟早会等待新提交的任务。您的执行函数总共只会添加 10 个新任务(moreTasks
初始化为 10 并不断减少,如果该计数器为零,则不会提交更多任务)。
因此,你could/should使用pthread_cond_timedwait
,自己醒来检查num_waiting_threads
状态。如果所有线程都在等待,跳出循环,退出线程。
我目前正在使用 POSIX 库并试用条件变量。 目前我正在使用一个队列来安排任务,如果有一个任务,一个线程使用 pthread_cond_signal 来唤醒一个正在等待 pthread_cond_wait 的线程。 然而,可能有一个点没有创建新任务,所以每个线程都在等待 pthread_cond_wait 并且程序卡在那里。
我是否注意到我的所有线程是否都在等待 pthread_cond_wait?我试过使用计数器和 leave 变量,但我没有让它工作。
我的代码看起来与此处的代码相似:https://code-vault.net/lesson/j62v2novkv:1609958966824 ,除了每个线程都在添加新任务(在 executeTask 中)而不是仅在主方法中添加它们。
编辑: 这是我上面网站的代码版本(正在为我加载:/)
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#define THREAD_NUM 4
typedef struct Task
{
int a, b;
} Task;
Task taskQueue[256];
int taskCount = 0;
// THIS VARIABLE IS ADDED
int moreTasks = 10;
pthread_mutex_t mutexQueue;
pthread_cond_t condQueue;
void executeTask(Task *task)
{
usleep(50000);
int result = task->a + task->b;
printf("The sum of %d and %d is %d\n", task->a, task->b, result);
// THIS PART IS ADDED
if (moreTasks > 0)
{
pthread_mutex_lock(&mutexQueue);
moreTasks--;
pthread_mutex_unlock(&mutexQueue);
Task t = {
.a = rand() % 100,
.b = rand() % 100};
submitTask(t);
}
}
void submitTask(Task task)
{
pthread_mutex_lock(&mutexQueue);
taskQueue[taskCount] = task;
taskCount++;
pthread_mutex_unlock(&mutexQueue);
pthread_cond_signal(&condQueue);
}
void *startThread(void *args)
{
while (1)
{
Task task;
pthread_mutex_lock(&mutexQueue);
while (taskCount == 0)
{
pthread_cond_wait(&condQueue, &mutexQueue);
}
task = taskQueue[0];
int i;
for (i = 0; i < taskCount - 1; i++)
{
taskQueue[i] = taskQueue[i + 1];
}
taskCount--;
pthread_mutex_unlock(&mutexQueue);
executeTask(&task);
}
}
int main(int argc, char *argv[])
{
pthread_t th[THREAD_NUM];
pthread_mutex_init(&mutexQueue, NULL);
pthread_cond_init(&condQueue, NULL);
int i;
for (i = 0; i < THREAD_NUM; i++)
{
if (pthread_create(&th[i], NULL, &startThread, NULL) != 0)
{
perror("Failed to create the thread");
}
}
srand(time(NULL));
for (i = 0; i < 100; i++)
{
Task t = {
.a = rand() % 100,
.b = rand() % 100};
submitTask(t);
}
for (i = 0; i < THREAD_NUM; i++)
{
if (pthread_join(th[i], NULL) != 0)
{
perror("Failed to join the thread");
}
}
pthread_mutex_destroy(&mutexQueue);
pthread_cond_destroy(&condQueue);
return 0;
}
我现在的问题是,一段时间后 taskCount 始终为零,因此我的所有线程都在 startThread
方法中的 pthread_cond_wait(&condQueue, &mutexQueue);
。
如果所有线程都在这个地方,我有什么办法注意到吗?如上文所述,如果已经尝试对当前正在等待的线程使用计数器(以及我计算正在工作的线程的版本),但我无法弄清楚如何在每个任务完成后停止所有线程。
如果您想知道有多少线程在等待条件变量,只需在进入等待模式之前增加一个全局计数器并在唤醒时减少它。有了它,您就会知道当前有多少线程正在等待。
例如
//global scope
int num_waiting_threads = 0;
//in function startThread
while (taskCount == 0)
{
//if num_waiting_threads == THREAD_NUM, all threads are waiting
++num_waiting_threads;
pthread_cond_wait(&condQueue, &mutexQueue);
--num_waiting_threads;
}
由于你有固定数量的任务,在处理完每个任务后,每个线程迟早会等待新提交的任务。您的执行函数总共只会添加 10 个新任务(moreTasks
初始化为 10 并不断减少,如果该计数器为零,则不会提交更多任务)。
因此,你could/should使用pthread_cond_timedwait
,自己醒来检查num_waiting_threads
状态。如果所有线程都在等待,跳出循环,退出线程。