两个线程情况下 用mutex 对bitmap加锁却不管用

delacrxoix_xu 2009-12-15 06:26:33
我想绘制mandelbrot集,用两个线程。分别绘制奇数列,偶数列。
但setpixel时候对bitmap的访问总是无法 互斥。 用 lock monitor mutex 都不行。

private static Bitmap t = new Bitmap(640, 480);

private Thread draw1 = null;
private Thread draw2 = null;
private static Mutex mutex = new Mutex();

private void Draw()
{
draw1 = new Thread(new ThreadStart(DrawMandelbrot_Odd));
draw2 = new Thread(new ThreadStart(DrawMandelbrot_Even));
draw1.Start();
draw2.Start();
pictureBox1.Image = t;
}

private void DrawMandelbrot_Odd()
{
for (int i = 0; i < pictureBox1.Width; i += 2)
{
for (int j = 0; j < pictureBox1.Height; j++)
{
int k;
for (k = 0; k < m_Times; k++)
{
。。。
}
Color c = 。。。;
lock (this)
{
mutex.WaitOne();
t.SetPixel(i, j, c);
mutex.ReleaseMutex();
}
}
}
}


private void DrawMandelbrot_Even()
{
for (int i = 1; i < pictureBox1.Width; i += 2)
{
for (int j = 0; j < pictureBox1.Height; j++)
{
x0 = 0;
y0 = 0;
double p = (double)pmin + dp * i;
double q = (double)qmin + dq * j;
int k;
for (k = 0; k < m_Times; k++)
{
getNextIter(iterTimes, x0, y0, p, q, out x, out y);
r = x * x + y * y;
x0 = x;
y0 = y;
if (r > m_Deep)
break;

}
red = 。。。;
green = 。。。;
blue = 。。。;
Color c = Color.FromArgb(red, green, blue);
lock (this)
{
mutex.WaitOne();
t.SetPixel(i, j, c);
mutex.ReleaseMutex();
}
}
}
}


总是在 t.SetPixel(i, j, c);处 出错, 说对象正在被使用。我少打了好多代码,
...全文
170 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
delacrxoix_xu 2010-07-07
  • 打赏
  • 举报
回复
早就搞定了,现在才来结贴。。。

1楼正解,不过我用的是一个数组,这样就不会冲突了。不同的线程写入不同的部分,不会造成互斥
delacrxoix_xu 2010-02-11
  • 打赏
  • 举报
回复
求高人帮忙 谢谢 老帖再顶一次
flyerwing 2010-02-11
  • 打赏
  • 举报
回复
学习,关注
大虾。
Jiacker 2010-02-11
  • 打赏
  • 举报
回复
楼主可以试试以下代码,不保证成功:
private static Bitmap t = new Bitmap(640, 480);

private Thread draw1 = null;
private Thread draw2 = null;
private static object _writeLock=new object();
private autoEvents = new AutoResetEvent[]
{
new AutoResetEvent(false),
new AutoResetEvent(false)
};


private void Draw()
{
draw1 = new Thread(new ThreadStart(DrawMandelbrot_Odd));
draw2 = new Thread(new ThreadStart(DrawMandelbrot_Even));
draw1.Start();
draw2.Start();
WaitHandle.WaitAll(autoEvents);
pictureBox1.Image = t;
}

private void DrawMandelbrot_Odd()
{
for (int i = 0; i < pictureBox1.Width; i += 2)
{
for (int j = 0; j < pictureBox1.Height; j++)
{
int k;
for (k = 0; k < m_Times; k++)
{
。。。
}
Color c = 。。。;
SetPixel(i, j, c);
}
}
autoEvents[0].Set();
}


private void DrawMandelbrot_Even()
{
for (int i = 1; i < pictureBox1.Width; i += 2)
{
for (int j = 0; j < pictureBox1.Height; j++)
{
x0 = 0;
y0 = 0;
double p = (double)pmin + dp * i;
double q = (double)qmin + dq * j;
int k;
for (k = 0; k < m_Times; k++)
{
getNextIter(iterTimes, x0, y0, p, q, out x, out y);
r = x * x + y * y;
x0 = x;
y0 = y;
if (r > m_Deep)
break;

}
red = 。。。;
green = 。。。;
blue = 。。。;
Color c = Color.FromArgb(red, green, blue);
SetPixel(i, j, c);
}
}
autoEvents[1].Set();
}

private void SetPixel(int i,int j,Color c)
{
lock(_writeLock)
{
try
{
t.SetPixel(i, j, c);
}
catch ()
{
}
}
}
delacrxoix_xu 2009-12-27
  • 打赏
  • 举报
回复
求高人帮忙
delacrxoix_xu 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cuike519 的回复:]
你是想弄出来动画效果么?这样是弄不出来的。。。

Bitmap这个对象不能被两个线程同时持有,线程互斥不是这么用的。

你可以在两个线程中分别绘制图形(都持有自己的bitmap对象),然后再两个线程都完成之后通知UI线程再合并两个图片。。。
[/Quote]

用 64*48 这类小尺度画布, 偶尔可以绘制成功,大部分时候都绘制到一半,调试出错。


UI合并可以吗? 合并之后存在哪个变量里? picturebox.image里面行吗? 或者某bitmap也行。求指教
cuike519 2009-12-15
  • 打赏
  • 举报
回复
你是想弄出来动画效果么?这样是弄不出来的。。。

Bitmap这个对象不能被两个线程同时持有,线程互斥不是这么用的。

你可以在两个线程中分别绘制图形(都持有自己的bitmap对象),然后再两个线程都完成之后通知UI线程再合并两个图片。。。

111,123

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧