总的来说,我是 C 语言的新手,我正在尝试使用 pthreads 制作一个小的图像过滤器。在使用指针和引用玩了几个小时之后,它通过了编译器,但随后出现了段错误,代码如下:
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
using namespace std;
using namespace cv;
#define WIDTH 3
#define HEIGHT 4
#define NUM_THREADS 4
struct readThreadParams{
Mat img;
Mat out;
int yStart;
int xEnd;
int yEnd;
int xRad;
int yRad;
};
//Find average of all pixels in WXH area
uchar getAverage(Mat &img, Mat &out, const float x1, const float y1, const int xRad, const int yRad){
//x1, y1: Pixel position being checked. xRad, yRad: how many pixels are being checked in x and y, relative to starting point.
uchar blue;
uchar green;
uchar red;
Vec3b outColor;
for (int c = 0; c < xRad; c++){
for (int r = 0; r < yRad; r++){
Vec3b intensity = img.at<Vec3b>(r, c);
blue =+ intensity.val[0];
green =+ intensity.val[1];
red =+ intensity.val[2];
}
}
outColor[0] = (blue/(xRad*yRad*4));
outColor[1] = (green/(xRad*yRad*4));
outColor[2] = (red/(xRad*yRad*4));
for (int c = 0; c< xRad; c++){
for (int r = 0; r< yRad; r++)
out.at<Vec3b>(Point(c, r)) = outColor;
}
}
void* parallel_processing_task(void * param){
//This is what each thread should do:
struct readThreadParams *input = (struct readThreadParams*)param;
Mat img = input->img;
Mat out = input->out;
const float yStart = input->yStart;
const float xEnd = input->xEnd;
const float yEnd = input->yEnd;
const float xRad = input->xRad;
const float yRad = input->yRad;
for (int c = 0; c < xEnd; c + xRad){
for (int r=yStart; r < yEnd; r + yRad){
getAverage(img, out, c, r, xRad, yRad);
}
}
}
int main(int argc, char *argv[]){
//prepare variables
pthread_t threads[NUM_THREADS];
void* return_status;
struct readThreadParams input;
int t;
Mat img = imread("image.jpg", IMREAD_COLOR);
int ROWS = img.rows;
int COLS = img.cols;
Mat out(ROWS, COLS, CV_8UC3);
input.img = img;
input.out = out;
input.xEnd = COLS;
input.xRad = WIDTH;
input.yRad = HEIGHT;
double t2 = (double) getTickCount();
for (int r = 0; r<ROWS ; ceil(ROWS/NUM_THREADS)){
input.yStart = r;
input.yEnd = r + ceil(ROWS/NUM_THREADS);
pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input);
}
for(t=0; t<NUM_THREADS; t++){
pthread_join(threads[t], &return_status);
}
t2 = ((double) getTickCount() - t2) / getTickFrequency();
//print execution time
cout << "Execution time: " << t2 << " s" << endl;
//result image
imwrite("output.png", out);
return(0);
}
我使用 GDB 找到了罪魁祸首,并设法找到它在第 107 行:
pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input);
在这一点上,我尝试到处寻找解决方案,我尝试了以下方法:
- 改变我定义结构的方式,让它接收指针,后来我发现这不起作用。
- 改变我传递参数的方式(例如添加或删除
(*void)
在它看起来合适的地方),最终导致了更大的困惑 错误或最后只是相同的错误。
此外,在尝试阅读 gdb bt 输出时,刚接触这种语言并不能真正帮助我:
#0__pthread_create_2_1(newthread=optimized out>, attr=<optimized out>, start_routine=<optimized out>, arg=<optimized out>) at pthread_create.c:601
#1 0x00011a00 in main(argc=1, argv=0x7efff394) at file.cpp:107
我的一部分想认为问题与优化
部分有关,但查找它没有产生任何结果,或者至少,我可能没有正确查找。
关于我在这里可能做错了什么有什么想法吗?非常感谢您的帮助!
最佳答案
在 t
中使用它之前,您还没有初始化
pthread_create(&threads[t], NULL, parallel_processing_task, (void *)&input);
因此这可能会导致未定义的行为,因为 t
可能具有任何可能使 &threads[t]
访问无效内存的值
关于C++:pthread_create 上的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47067737/