我正在尝试处理图像的实验,其中我正在修改每个像素中的颜色。我尝试使用" buckets"来实现我的代码,其中我将图像划分为更小的区域 - 每个区域都接收一个专用的线程来处理图像。
在我的结尾,我真的不在乎多个线程是否正在尝试修改相同的资源,事实上,这似乎是重点。从理论上讲,线程应该以像素的形式修改存储器中的不同位置。然而,当打印我的结果时,只有第一个任务似乎在迭代 - 让我认为某种竞争条件正在发生。
以下功能管理每项任务的创建,以及 为它提供起始坐标和跨度来操作。一世 相信这工作正常,但这只是为了上下文:
Image*
CCManager::CCAsync(uint8_t bucketSize, Image* source,
const std::vector<float>& correction)
{
Image* newImg = new Image(); // This will contain our end result
newImg->resize(source->width(), source->height());
assert(buckets > 0);
// Now compute the width and height each bucket will render.
uint32_t width;
uint32_t height;
if(buckets == 2) // Each bucket takes a vertical rectangle
{
width = source->xSize()/2;
height = source->ySize();
}
else
{
// Set width and height to produce square grids (powers of 2)
// *** Not shown for Brevity ***
}
std::vector<std::thread> tasks; // The threads we are managing
// These coordinates will be fed as starting locations for each task
uint32_t startX = 0;
uint32_t startY = 0;
uint8_t tasksFinished = 0;
for(int i = 1; i <= buckets; ++i)
{
// Create a new task with a region for operation
tasks.emplace_back(std::thread(&CCManager::applyCCTask,this, startX, startY,
width, height, source, newImg, correction));
// No iteration is required for 1 bucket, simply paint the whole image
if(buckets == 1){break;}
// **** I REMOVED PART OF THE CODE THAT SHOWS WHERE EXPONENT
// IS DEFINED AND DETERMINED FOR BREVITY
// Reached last column, start a new row
if(i % exponent == 0)
{
startX = 0;
startY+= height;
}
// Keep incrementing horizontally
else
{
startX+= width;
}
}
while(tasksFinished < buckets)
{
// Join with whichever tasks finished
for(int i = 0; i < buckets; ++i)
{
if(tasks[i].joinable())
{
tasks[i].join();
tasksFinished++;
}
}
}
tasks.clear();
return newImg;
}
为每个任务提供了新的和源图像指针,这里它们正在运行。
follow函数检索每个像素中的颜色,并调用a 相应地应用修正的方法。
void
CCManager::applyCCTask(uint32_t x, uint32_t y, uint32_t width, uint32_t height,
Image* source, Image* newImg,
const std::vector<float>& correction)
{
// ** THIS ACTUALLY PRINTS THE CORRECT COORDINATES AND REGION SPAN
// ** FOR EACH THREAD
printf("Task renders @ (%i,%i) with %i x %i box\n", x,y,width,height);
assert(source);
assert(newImg);
for (; x < width; ++x )
{
for (; y < height; ++y)
{
Byte4 pixel = source->pixel (x, y);
Color color = pixel.color;
printf("Before correction: Pixel(%i,%i) color [%i,%i,%i]\n",x,y, pixel.color[0], pixel.color[1], pixel.color[2]);
Color correctedColor= addCorrectionToColor( color, correction);
Byte4* newPixel= &newImg->pixel( x, y );
newPixel->color[0] = correctedColor[0];
newPixel->color[1] = correctedColor[1];
newPixel->color[2] = correctedColor[2];
printf("After correction: Pixel(%i,%i) color [%i,%i,%i]\n",x,y, newImg->pixel( x, y ).color[0], newImg->pixel( x, y ).color[1], newImg->pixel( x, y ).color[2]);
}
}
printf("Task Finished!\n");
}
显示代码后,所有任务最终都会根据其操作区域打印起始消息,但在嵌套循环内,&#34;之前&#34;和#34;之后&#34;消息似乎只打印一个任务。
为什么我不允许从多个线程修改相同的图像,即使每个线程修改的实际像素数据不同?我是否可以在不添加互斥锁等资源锁的情况下绕过这一点,本实验的重点是允许每个线程独立运行而不受任何阻碍。