使用 pthread 的分段错误

Segmentation Fault using pthread

我正在创建一个简单的程序来打开 .rgba 文件并旋转它。 用 gcc code.c -o x -lm -lpthread 编译,我在 运行 ./x img.rgba 90 之后得到了 'Segmentation fault'。用gdb调试,崩溃发生在pthread_create(),但不知道为什么。去掉pthread_join(),segfault消失了,但是逻辑就错了。

#define WIDTH  512
#define HEIGHT 512
#define NUM_THREADS 16
#define WIDTH_BLOCK 1

unsigned int img_orig [HEIGHT][WIDTH];
unsigned int img_rot [HEIGHT][WIDTH];
int nlin = 0;
int ncol = 0;

typedef struct {
    int i_start;
    int i_end;
    int j_start;
    int j_end;
    int * xc;
    int * yc;
    float * s;
    float * c;
} thread_arg;

void *thread_func(void * arg) {
    // do some logic
}

int
main(int argc, char **argv)
{
    ...

    memset(img_rot, 0, WIDTH * HEIGHT * sizeof(int));

    for (i = 0; i < nlin; i++)
        for (j = 0; j < ncol; j++)
            read(fd, &img_orig[i][j], 4);
    close(fd);
    xc = ncol / 2;
    yc = nlin / 2;

    angle = angle * M_PI / 180.0;
    s = sin(angle);
    c = cos(angle);
    int step = HEIGHT / NUM_THREADS;

    for (i = 0; i < nlin; i += step) {
        for (j = 0; j < ncol ; j += WIDTH / WIDTH_BLOCK) {
            thread_arg * arg = (thread_arg *) malloc(sizeof(thread_arg));
            arg->i_start = i;
            arg->i_end = i + step;
            arg->j_start = j;
            arg->j_end = j + (WIDTH / WIDTH_BLOCK);
            arg->xc = &xc;
            arg->yc = &yc;
            arg->s = &s;
            arg->c = &c;

            // inicia a thread
            if (pthread_create(&(threads[i]), NULL, thread_func, arg))
                printf("Error");

        }
    }
    // aguarda todas threads acabarem
    for (i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }


    return 0;
}
for (i = 0; i < nlin; i += step) {
    for (j = 0; j < ncol ; j += WIDTH / WIDTH_BLOCK) {
        thread_arg * arg = (thread_arg *) malloc(sizeof(thread_arg));
        arg->i_start = i;
        arg->i_end = i + step;
        arg->j_start = j;
        arg->j_end = j + (WIDTH / WIDTH_BLOCK);
        arg->xc = &xc;
        arg->yc = &yc;
        arg->s = &s;
        arg->c = &c;

        // inicia a thread
        if (pthread_create(&(threads[i]), NULL, thread_func, arg))
            printf("Error");

    }
}

如果你的内循环运行不止一次,当你得到第二个线程的pthread_t时,你将覆盖第一个线程的pthread_t

如果要创建 16 个线程,则需要编写的代码在创建线程时循环次数不超过 16 次。您的外循环确实循环了 16 次。您需要将内部循环移动到线程内部。

'nlin' 使用 'HEIGHT' (512) 进行初始化,您可以使用索引 'i' 访问 'threads' 数组,这取决于 'nlin'。你的 'threads' 数组又有多大?