pthreadsを使用してマルチスレッドプログラムを作成しています。発想は単純です:Pthreads - 条件変数とmutexを持つプロデューサとコンシューマ - 結合エラーと奇妙なCout
- カー(スレッド)
- ガソリン供給(スレッド)
- ガソリンスタンド(リソース)
両方の車とガソリンステーションは、いくつかの燃料容量を持っており、車の後にされましたガソリンスタンドを訪問する必要があります。ガソリンスタンドに燃料がなくなると、ガソリン供給スレッドが稼動し、資源を補充します。すべては、私がpthread_join
の代わりにpthread_exit
を使用して、主な機能のスレッドを待つ必要があり、時には同じ車のためにcout
をダブルしなければならないということを除いて、うまくいくようです:"-----End of fuel-----"
。 私はそれを正しくやっていますか?
構造体といくつかのグローバル変数:
#define initialFuel 100
#define loop 10
pthread_mutex_t mutex1, mutex2;
pthread_cond_t isempty;
PetrolDistributor petrolDistributor;
struct Car {
int capacity = 10;
int petrol = 5;
};
struct PetrolDistributor {
int petrol = initialFuel;
bool isEmpty = false;
};
スレッド:
void * threadSupply(void *arg)
{
for(int i = 0; i<loop; i++)
{
pthread_mutex_lock(&mutex1);
while(!petrolDistributor.isEmpty)
{
pthread_cond_wait(&isempty, &mutex1); //When signal received, do below:
usleep(2000000);
petrolDistributor.petrol = initialFuel; //Refill petrol and change state
petrolDistributor.isEmpty = false;
}
pthread_mutex_unlock(&mutex1);
}
}
void * threadPetrolDriver(void *arg)
{
Car *car;
car = (Car*) arg;
for(int i = 0; i<loop; i++)
{
while(car->petrol > 0) // Car consumes petrol here
{
usleep(200000);
cout << car->petrol << endl;
car->petrol -= 1;
}
cout << "-----End of fuel-----" << "\t\t #" << i << endl;
pthread_mutex_lock(&mutex1);
if (petrolDistributor.petrol >= 30) // If distributor almost empty?
{
petrolDistributor.petrol -= car->capacity; //Substract car's capacity amount of fuel from distributor
car->petrol = car->capacity; //Fillup mentioned capacity in car
}
else
{
petrolDistributor.isEmpty = true;
pthread_cond_signal(&isempty);
}
pthread_mutex_unlock(&mutex1);
}
}
メイン:
int main()
{
pthread_t car;
pthread_t supply;
Car carPetrol;
pthread_cond_init(&isempty, NULL);
pthread_mutex_init(&mutex1, NULL);
pthread_create(&car, NULL, threadPetrolDriver, (void*) (&carPetrol));
pthread_create(&supply, NULL, threadSupply, NULL);
// pthread_join(&car, NULL); //results error: invalid conversion from ‘pthread_t* {aka long unsigned int*}’ to ‘pthread_t {aka long unsigned int}’ [-fpermissive]|
// pthread_join(&supply, NULL);
pthread_exit(NULL);
return 0;
}
出力例:
-----End of fuel----- #0
9
(...)
2
1
-----End of fuel----- #1
-----End of fuel----- #2 //Also for loop increments
10
9
(...)
3
2
1
-----End of fuel----- #3
10
9
(...)
、出力はそのように見えない理由の質問はありますか?時には5回の反復がうまくいき、6回目にダブルメッセージが表示されます。そして、参加に間違いはありますか? アドバイスをいただきありがとうございます。
'pthread_cond_t'を初期化する必要性を認識しているようですが、あなたの' pthread_mutex_t'sをデフォルトで初期化したままの内容であるように見えるのは少し不思議です。また、 'pthread_cont_t'がセマフォーであると思われるようです。そうではない。 – EOF
答えを出してくれてありがとう、ミューテックスの初期化がありません。私が他のStackのトピックを尋ねるときに、あなたのアドバイスの2番目の部分をどのように使うのか分かりません。人々は 'pthread_mutex_t'と' pthread_cont_t'をそういう形で混ぜるように勧めましたが、間違っている可能性があります – Macieyo
注:pthread_join() pthread_idですが、あなたはpthread_tを提供しています。同じことではありません。 (これは彼の(主な)質問ではないので、答えではありません。) –