使用 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' 数组又有多大?
我正在创建一个简单的程序来打开 .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' 数组又有多大?