#gcc #pthreads #raytracing
#gcc #pthreads #трассировка лучей
Вопрос:
int main(int a, char *args[]) {
int i;
pthread_t threads[8];
unsigned int* pixmap = malloc(1024*1024*sizeof(int));
v_threadargs.height = 1024.0f;
v_threadargs.width = 1024.0f;
v_threadargs.pixmap = pixmap;
for (i = 0; i < 8; i ) {
v_threadargs.threadid = i;
pthread_create(amp;threads[i], NULL, render, (void *) amp;v_threadargs);
}
for (i = 0; i < 8; i )
pthread_join(threads[i], NULL);
writetga(pixmap, 1024, 1024, "ray8out.tga");
free(pixmap);
pthread_exit(NULL);
return 0;
}
void *render(void *r_threadargs) {
int i,j, threadid, start;
float height, width;
int *pixmap;
struct s_threadargs *p_threadargs;
p_threadargs = (struct s_threadargs *) r_threadargs;
height = p_threadargs -> height;
width = p_threadargs -> width;
pixmap = p_threadargs -> pixmap;
threadid = p_threadargs -> threadid;
stepy = viewplaney0;
deltax = (viewplanex1 - viewplanex0) / width;
deltay = (viewplaney1 - viewplaney0) / height;
stepy = deltay;
float *viewer = (float[3]){0.0f, 0.0f, -7.0f};
if (threadid == 1)
start = 0;
else
start = threadid * height/8;
for (i = start; i < (threadid 1)*(height/8); i ) {
stepx = viewplanex0;
for (j = 0; j < width; j ) {
float *color = (float[3]){0.0f, 0.0f, 0.0f};
float *raydir = (float[3]){stepx - viewer[0], stepy - viewer[1], 0 - viewer[2]};
float maxdist = 100000.0f;
normalize(raydir);
trace(raydir, viewer, color, 0,maxdist);
int r = (int)(roundf(color[0]*255.0f));
if (r > 255) { r = 255; }
int g = (int)(roundf(color[1]*255.0f));
if (g > 255) { g = 255; }
int b = (int)(roundf(color[2]*255.0f));
if (b > 255) { b = 255; }
pixmap[j i*(int)width] = (r << 16) | (g << 8) | (b);
stepx = deltax;
}
stepy = deltay;
}
}
Я пытаюсь реализовать эту программу raytracer с использованием 8 потоков (pthreads с использованием gcc), но выводимое изображение «ray8out.tga» неверно. Программа выполняется корректно, без каких-либо ошибок, но чего-то не хватает в логике. Было бы приятно, если бы кто-нибудь, пожалуйста, мог мне помочь, где ошибка?
Ответ №1:
Вы передаете одну и ту же структуру threadargs каждому потоку; нет гарантии, что они начнут выполняться до того, как вы измените значение threadid. Вы должны выделить новую структуру threadargs с помощью malloc для каждого потока (и освободить ее внутри самого нового потока).
Комментарии:
1. На самом деле я новичок в потоках. Вы имеете в виду, что: для (i = 0; i < 8; i ) { v_threadargs[i].height = 1024.0f; v_threadargs [i].width = 1024.0f; v_threadargs[i].pixmap = пиксельная карта; v_threadargs[i].threadid = i; pthread_create (amp;потоки [i], NULL, визуализация, (void *) amp; v_threadargs[i]); }
2. @Bilal, да, использование массива — это вариант, а также до тех пор, пока v_threadargs остается неизменным, пока все потоки не будут объединены.