我创建了多个线程,并希望使用条件变量以循环方式运行它们 和信号(pthread_cond_wait& pthread_cond_signal)。
我使用了两种方法,一种方法正在工作但浪费CPU而其他方法无效, 不要浪费CPU。
我面临的问题是之前发送的信号 我的线程等待,信号丢失。所以它会进入无限的等待循环。
第一种方法:
创建线程并等待条件变量并持续检查被调用的变量 作为状态(在while循环中)。
当state == my_id时,带有my_id的线程被激活,然后它发信号到下一个线程my_id + 1等等 上。
DRAWBACK:CPU的浪费
第二种方法:
创建线程并等待其自身条件变量的信号。现在信号已经存在 在线程开始等待之前发送,信号丢失,程序进入无限等待循环。
是否有类似" Self Signaling"或者在信号丢失时发送信号的其他方式?
我在linux下使用g ++。任何线索都将受到高度赞赏。提前谢谢。
第一种方法的计划在round robin。
这是我的第二种方法:
#include <pthread.h>
#include <stdio.h>
#include <iostream>
#include <mutex> // std::mutex
#define MULTIPLE_THREADS 2
#define NTHREADS MULTIPLE_THREADS*64
#define NO_OF_LOOP 1
pthread_cond_t cond[NTHREADS];
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
using namespace std;
/* This is our thread function. It is like main(), but for a thread*/
void *threadA(void *arg)
{
long my_id = (long)arg;
int i = 0;
while(i < NO_OF_LOOP)
{
// Awaken or unblocked by thread (i-1)
pthread_mutex_lock(&mutex1);
pthread_cond_wait(&cond[my_id], &mutex1);
pthread_mutex_unlock(&mutex1);
printf("I am thread - %ld",my_id);
++i;
/* wake up thread i+1 */
pthread_mutex_lock(&mutex1);
pthread_cond_signal(&cond[(my_id + 1) % NTHREADS]);
pthread_mutex_unlock(&mutex1);
}
return NULL;
}
int main(void)
{
pthread_t threadid[NTHREADS];
// Initialization
for(int i=0;i<NTHREADS;i++)
cond[i]= PTHREAD_COND_INITIALIZER;
//printf("Create %d threads\n", NTHREADS);
for(long i=0; i<NTHREADS; ++i) {
pthread_create(&threadid[i], NULL, threadA, (void *)i);
//printf("Thread created=%d\n", i);
}
// printf("Wait for threads and cleanup\n");
for (long i=0; i<NTHREADS; ++i) {
pthread_join(threadid[i], NULL);
}
return 0;
}
答案 0 :(得分:2)
您不能以这种方式使用条件变量。你总是需要一个谓词。也就是说,你需要 一个变量,您可以测试事件是否已发生。
简单地发出盲目的pthread_cond_wait和pthread_cond_signal会让你输掉比赛。 可能有spurious wakeups,如果您发信号的线程未在pthread_cond_wait()中被阻止,它将错过该事件(pthread_cond_signal()不排队)。
你需要这样的东西(未经测试):
pthread_cond_t cond[NTHREADS];
int wakeup[NTHREADS];
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
using namespace std;
/* This is our thread function. It is like main(), but for a thread*/
void *threadA(void *arg)
{
long my_id = (long)arg;
int i = 0;
while(i < NO_OF_LOOP)
{
// Awaken or unblocked by thread (i-1)
pthread_mutex_lock(&mutex1);
while (!wakeup[my_id]) {
pthread_cond_wait(&cond[my_id], &mutex1);
}
wakeup[my_id] = 0;
pthread_mutex_unlock(&mutex1);
printf("I am thread - %ld",my_id);
++i;
pthread_mutex_lock(&mutex1);
//tell thread i to wake up
wakeup[(my_id + 1) % NTHREADS] = 1;
pthread_cond_signal(&cond[(my_id + 1) % NTHREADS]);
pthread_mutex_unlock(&mutex1);
}
return NULL;
}
int main(void)
{
pthread_t threadid[NTHREADS];
wakeup[0] = 1; //let thread 0 start.
EDIT。 #define NTHREADS MULTIPLE_THREADS*64
宏也出现了另一个错误。
表达式(my_id + 1) % NTHREADS
将无法正确计算,宏必须为
#define NTHREADS (MULTIPLE_THREADS*64)
由于stdout通常是行缓冲的,因此在printf中添加换行符,以便立即看到输出。
printf("I am thread - %ld\n",my_id);