linux 为什么使用pthread_join时输出会出错?

slwdgvem  于 2022-12-26  发布在  Linux
关注(0)|答案(1)|浏览(145)

我还在学习线程,我试图在我的代码中解决这个问题,当我把pthread_join(thread[i],NULL)放在创建线程的循环之外时,它总是给我错误的输出,ID = 0的线程将不工作(调用中值func),最后一个线程将工作两次,为了更好地理解,请参见下面的输出:

ThreadID= 0, startRow= 0, endRow= 0      // first thread doesn't call the median func
ThreadID= 1, startRow= 1, endRow= 1
ThreadID 1 numOfBright 0 numOfDark 1 numOfNormal 4
ThreadID= 2, startRow= 2, endRow= 2
ThreadID 2 numOfBright 0 numOfDark 1 numOfNormal 4
ThreadID= 3, startRow= 3, endRow= 3
ThreadID 3 numOfBright 0 numOfDark 0 numOfNormal 5
ThreadID= 4, startRow= 4, endRow= 4
ThreadID 4 numOfBright 0 numOfDark 5 numOfNormal 0  
ThreadID 4 numOfBright 0 numOfDark 5 numOfNormal 0 // last thread is calling the median func two times.

这是打印每个线程的开始行和结束行的代码部分。

pthread_t* threads = new pthread_t[num_threads];
    struct Th_Range* RANGE = (struct Th_Range*)malloc(sizeof(struct Th_Range*));
    int thread_status;
    RANGE->SizeOfImage = r; // 2d array with size (n*n) so rows(r) = columns(c) 
    if (n == num_threads) {  //rows = num of threads then every thread will work in a single row
        for (int i = 0; i < num_threads; i++) {
            RANGE->ThreadId = i;
            RANGE->StartRow = RANGE->EndRow = i;
            cout << "ThreadID= " << i << ", startRow= " << RANGE->StartRow << ", endRow= " << RANGE->EndRow << endl;
            thread_status = pthread_create(&threads[i], NULL, Median, RANGE);
            if (thread_status) 
        exit(-1);
                                             } //for loop ends here
           for (int i = 0; i < num_threads; i++)
           pthread_join(threads[i],NULL);
  } //end of if statement

下面是median函数和上述if语句所需的部分代码。

#include <iostream>
#include <bits/stdc++.h>
#include <pthread.h>
 
pthread_mutex_t Lock;
pthread_mutex_t Pixels;
pthread_mutex_t Pixels2;
using namespace std;
 
int numOfBright, numOfDark, numOfNormal;
int** Oimage, ** Fimage; //original and filtered image
struct Th_Range {
    int SizeOfImage;
    int StartRow;
    int EndRow;
    int ThreadId;
};
void* Median(void* par)
{
    struct Th_Range* Num = (struct Th_Range*)par;
    int StartRow = Num->StartRow;
    int EndRow = Num->EndRow;
    int Size = Num->SizeOfImage;    
    int Neighbour[9] = { 0 };
    int dark = 0, bright = 0, normal = 0;
    if (EndRow == StartRow)   
        EndRow += 2;
    else
        EndRow++;
    for (int i = StartRow +1; i < EndRow ; i++)
    {
        for (int j = 1; j < Size - 1; j++)
        {
            Neighbour[0] = Oimage[i - 1][j - 1];
            Neighbour[1] = Oimage[i - 1][j];
            Neighbour[2] = Oimage[i - 1][j + 1];
            Neighbour[3] = Oimage[i][j - 1];
            Neighbour[4] = Oimage[i][j];
            Neighbour[5] = Oimage[i][j + 1];
            Neighbour[6] = Oimage[i + 1][j - 1];
            Neighbour[7] = Oimage[i + 1][j];
            Neighbour[8] = Oimage[i + 1][j + 1];
 
            pthread_mutex_lock(&Pixels); //it can be moved only to lock the Fimage and the numOfBright or any other global variables
            sort(Neighbour, Neighbour + 9);
            Fimage[i][j] = Neighbour[4];
            if (Neighbour[4] > 200) {
                bright++;
                numOfBright++;
            }
            else if (Neighbour[4] < 50) {
                dark++;
                numOfDark++;
            }
            else {
                normal++;
                numOfNormal++;
            }
            pthread_mutex_unlock(&Pixels);
        }
    }
    pthread_mutex_lock(&Pixels2);  //when I try to remove this lock the output gets interrupted
    cout << "ThreadID " << Num->ThreadId << " numOfBright " << bright << " numOfDark " << dark << " numOfNormal " << normal<<endl;
    pthread_mutex_unlock(&Pixels2);
    pthread_exit(NULL);
}
 
int main(int argc, char* argv[])
{
    int num_threads, n, r, c;  // n is the size of the matrix r and c are rows and columns
 
    numOfNormal = numOfDark = numOfBright = 0;
    if (argc >= 2)
        num_threads = atoi(argv[1]);
    else
        exit(-1);
 
    ifstream cin("input.txt");
 
 
    cin >> n;
    r = c = n + 2;
 
    Oimage = new int* [r]();
    Fimage = new int* [r]();
 
    for (int i = 0; i < c; i++)
    {
        Oimage[i] = new int[c]();
        Fimage[i] = new int[c]();
    }
 
    for (int i = 1; i < r - 1; i++)  
        for (int j = 1; j < c - 1; j++)
            cin >> Oimage[i][j];
 
    
 
  
    pthread_t* threads = new pthread_t[num_threads];
    struct Th_Range* RANGE = (struct Th_Range*)malloc(sizeof(struct Th_Range*));
 
    RANGE->SizeOfImage = r;
    if (n == num_threads) {  //rows = num of threads then every thread will work in a single row
        //n+2 
    int thread_status;
        for (int i = 0; i < num_threads; i++) {
            RANGE->ThreadId = i;
            RANGE->StartRow = RANGE->EndRow = i;
         //   pthread_mutex_lock(&Lock);
            cout << "ThreadID= " << i << ", startRow= " << RANGE->StartRow << ", endRow= " << RANGE->EndRow << endl;
            
            thread_status = pthread_create(&threads[i], NULL, Median, RANGE);
        
            if (thread_status) 
        exit(-1);
    }

  }

我试着把pthread_join移到pthread_create的循环中,它给出了正确的输出,但当然这是一个错误的解决方案。我不知道下一步该怎么做。提前感谢

8zzbczxx

8zzbczxx1#

也许你应该使用#include或者(使用名称空间sff)它必须工作

相关问题