C программирование - структура pthread_create () в качестве параметра - PullRequest
0 голосов
/ 23 января 2020

Я разработал пример, демонстрирующий многопоточность с использованием POSIX при обработке изображения. Кодирование было сделано с библиотекой lodepng. Я хотел, чтобы код разбил цветной инверсионный процесс любого загруженного изображения на 4 равных потока. Хотя я неоднократно проверял, я все еще не могу выяснить, почему начальные и конечные значения 4-го потока модифицируются внутри функции threadFunc2 (). Это тот же код, который используется другими 3 потоками, получая правильные начальные и конечные значения. Я использовал структуру для передачи данных начала, конца и номера потока в функцию. Например, если я загружаю изображение 10x10, которое дает 100 пикселей (каждое с 4 значениями для R, G, B и Transparency), для хранения каждого значения цвета требуется массив из 400 элементов. 4-й поток должен начинаться с 300 и 399. Он правильно рассчитывается в функции main () перед переходом к функции, но заканчивается как 5 и 6 в threadFunc2 () при запуске.

#include <pthread.h>
#include "lodepng.h"
#include <stdio.h>
#include <stdlib.h>
#include "lodepng.c"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 
unsigned int error;
unsigned int encError;
unsigned char* image;
unsigned int width;
unsigned int height;
int Arraysize;
const char* filename = "10x10Circle.png";
const char* newFileName = "10x10Result.png";    
struct Markers{int start;int end;int no};
void *threadFunc(void *arg){ // function to load the image into an array
    pthread_mutex_lock(&mutex);
    error = lodepng_decode32_file(&image, &width, &height, filename);
    if(error){
        printf("error %u: %s\n", error, lodepng_error_text(error));
    }
    Arraysize = 4*height*width;
    printf("arraysize:%d, %d \n",sizeof(image)/sizeof(image[0]),Arraysize);        
    pthread_mutex_unlock(&mutex);   
    return NULL;    }
void *threadFunc2(void *arg){ //function to apply inverse process on loaded data
   struct Markers*vars= (struct Markers*) arg;
   printf("Thread %d start|start-%d,end-%d\n",vars->no,vars->start,vars->end);
   for( int i = vars->start; i<(vars->end); i=i+4){
    pthread_mutex_lock(&mutex);
    image[0+i]= 255-image[0+i];
    image[1+i]= 255-image[1+i];
    image[2+i]= 255-image[2+i];
    image[3+i]= 255-image[3+i];//  can be ignored
    printf("Thread: %d,round:%d\n",vars->no,i);// debug line
    pthread_mutex_unlock(&mutex);
   }
  // printf("Thread: %d,after end:%d\n",vars->no,i);
     printf("**************************\n");
printf("Thread end\n");
return NULL;
}
void *encodeprocessed(){
    encError = lodepng_encode32_file(newFileName, image, width, height);
   if(encError){
    printf("error %u: %s\n", error, lodepng_error_text(encError));  }
   free(image);   }

Следующий это основная функция

int main(void){
  pthread_t pth,pth0, pth1, pth2, pth3;
  pthread_create(&pth,NULL,threadFunc,NULL);
  pthread_join(pth, NULL );
  struct Markers Positions[3];
  Positions[0].start = 0;
  Positions[0].end = Arraysize/4 -1;
  Positions[0].no = 1;
  Positions[1].start =Arraysize/4;
  Positions[1].end = Arraysize/2 -1;
  Positions[1].no = 2;
  Positions[2].start =Arraysize/2;
  Positions[2].end = Arraysize*3/4 -1;
  Positions[2].no = 3;
  Positions[3].start =(Arraysize*3)/4;
  Positions[3].end = Arraysize -1;
  Positions[3].no = 4; 
  //debug line
  printf("%d,%d,%d,%d,%d,%d,%d,%d,%d\n",Arraysize,Positions[0].start,Positions[0].end, 
  Positions[1].start,Positions[1].end,Positions[2].start,Positions[2].end,
  Positions[3].start,Positions[3].end);
  pthread_create(&pth0,NULL,threadFunc2,&Positions[0]);
  pthread_create(&pth1,NULL,threadFunc2,&Positions[1]);
  pthread_create(&pth2,NULL,threadFunc2,&Positions[2]);
  pthread_create(&pth3,NULL,threadFunc2,&Positions[3]);
  pthread_join(pth0, NULL );
  pthread_join(pth1, NULL );
  pthread_join(pth2, NULL );
  pthread_join(pth3, NULL );
  encodeprocessed();
  return 0;}

Код работает без ошибок. Изображение переворачивается только на 75% и сохраняется. Любой, кто может дать мне подсказку, высоко ценится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...