我遇到的问题是:我的“父母”经历了一个从 0 到 4 的 for 循环。在每次迭代中,我有 3 个线程要打印出它们的 12 个数字的“段”(0 到11)。
例如,当父循环为 0 时,线程 0 会打印出 0,线程 1 会打印出 4,线程 2 会打印出 8。
当父循环为 1 时,线程 0 会打印出 1,线程 1 会打印出 5,线程 2 会打印出 9。
所以理想的输出是 0 1 2 3 4 5 6 7 8 9 10 11 。我知道您无法确定线程何时运行,因此不会完全按照该顺序运行,但我至少希望在线程打印 3 4 或 5 之前打印 0 1 和 2。
这就是我遇到的问题。似乎一个或另一个线程被留在尘土中并且没有打印出它的片段,或者没有完全打印出它的片段以及其他线程。这是我正在尝试完全理解信号量的问题。
我有两个信号量,一个在线程工作时阻塞父级(生产者?),另一个阻塞每个线程,直到生产者增加到下一个索引。我认为通过这种方式我可以强迫他们在继续之前等待对方完成,但由于某种原因我遇到了问题。
这是我的代码:
#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);
}
}
如何确保所有线程在父级递增之前运行?如何确保所有线程每“轮”运行一次而没有任何卡在后面?有时同一个线程运行两次而不是每个线程运行一次.....帮助?
非常感谢大家的帮助。
编辑:新代码状态:(线程函数)
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);
}