私が抱えている問題は次のとおりです。「親」が0から4までのforループを通過します。各反復で、12個の数値(0から4)の「セグメント」を出力する3つのスレッドがあります。 11)。
たとえば、親ループが0の場合、スレッド0は0を出力し、スレッド1は4を出力し、スレッド2は8を出力します。
親ループが1の場合、スレッド0は1を出力し、スレッド1は5を出力し、スレッド2は9を出力します。
したがって、理想的には、出力は0 1 2 3 4 5 6 7 8 91011になります。スレッドがいつ実行されるかを判断できないことはわかっているので、正確にその順序になるわけではありませんが、スレッドが3 4または5を印刷する前に、少なくとも01と2を印刷したいと思います。
それが私が問題を抱えていることです。あるスレッドまたは別のスレッドがほこりの中に残って、そのセグメントを印刷しないか、他のスレッドと一緒にそのセグメントを完全に印刷しないようです。これは、セマフォを完全に理解するために私が行っている問題です。
2つのセマフォがあります。1つはスレッドが機能しているときに親(プロデューサー?)をブロックし、もう1つはプロデューサーが次のインデックスにインクリメントするまで各スレッドをブロックします。このようにして、お互いが終了するのを待ってから続行するように強制できると思いましたが、何らかの理由で問題が発生しています。
これが私のコードです:
#include <semaphore.h>
#include <stdio.h>
#include <pthread.h>
#define maxNum 12
sem_t parentSem;
sem_t threadSem;
int finishedThreads;
int done = 0;
int stuff[12];
int i;
void* threadFunction(int m){
int printNum;
int baseNum;
//Determine the value the thread should start at
baseNum = (double)(maxNum/3) * m;
while(!done){ //ensure thread doesn't exit before parent is done with whole loop
//wait for parent to increment
sem_wait(&threadSem);
printNum = baseNum + i;
//keep track of how many threads are finished to let parent continue
finishedThreads++;
if(finishedThreads == 3){
//let parent continue if all threads are finished
sem_post(&parentSem);
}
}
}
int main(int argc, char** argv[]){
sem_init(&parentSem, 0, 1);
sem_init(&threadSem, 0, 0);
int rc;
pthread_t threads[3];
int l;
for(l = 0; l < 12; l++){
stuff[l] = l;
}
int j;
for(j = 0; j < 3; j++){
rc = pthread_create(&threads[i], NULL, threadFunction, (void*) j);
}
int k;
for(i = 0; i < 4; i++){
sem_wait(&parentSem); //wait for children here (initially sem set to 1)
finishedThreads = 0; //set finished thread counter to 0
for(k = 0; k < 3; k++){
//increment thread semaphore to 3 so each thread can run
sem_post(&threadSem);
}
}
for(i = 1; i < 3; i++){
pthread_join(threads[i], NULL);
}
}
親がインクリメントする前にすべてのスレッドが実行されるようにするにはどうすればよいですか?すべてのスレッドが「ラウンド」ごとに実行され、遅れることがないようにするにはどうすればよいですか?各スレッドが1回実行されるのではなく、同じスレッドが2回実行されることがあります。
どうもありがとうございました。
編集:新しいコードの状態:(スレッド関数)
while(!done){
printf("Thread %d not done yet...\n", m);
if(m == 0){
sem_wait(&threadSem0);
}else if(m == 1){
sem_wait(&threadSem1);
}else if(m == 2){
sem_wait(&threadSem2);
}
printNum = baseNum + i;
printf("Thread %d past waiting, number segment: %d\n", m, printNum);
finishedThreads++;
if(finishedThreads == 3){
sem_post(&parentSem);
}
}
親部分:
for(i = 0; i < 4; i++){
printf("In parent for loop, counter: %d\n", i);
printf("Parent past wait semaphore\n");
finishedThreads = 0;
if(i == 3) done = 1;
sem_post(&threadSem0);
sem_post(&threadSem1);
sem_post(&threadSem2);
sem_wait(&parentSem);
}
for(i = 1; i < 3; i++){
pthread_join(threads[i], NULL);
}