Я разработал пример, демонстрирующий многопоточность с использованием 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% и сохраняется. Любой, кто может дать мне подсказку, высоко ценится.