std :: mutex作为成员变量对多个线程是线程安全的吗?

时间:2018-07-17 03:34:14

标签: c++ multithreading thread-safety mutex

std :: mutex是多线程线程安全的成员变量吗?

有一个类的实例,该实例具有变量和互斥量作为成员。

每个函数在不同的线程中调用。

我很好奇可以使用这样的互斥锁吗?

很多示例代码都使用一种针对互斥量的包装类,例如保护之类的东西。

我更喜欢简单地使用它,并且希望显式解锁。不会破坏时间。

private bool GetPixelColors(Image Bunker, WriteableBitmap wb)
{
    bool ret = false;
    double BunkerLeft = (double)Bunker.GetValue(Canvas.LeftProperty);
    double BunkerTop = (double)Bunker.GetValue(Canvas.TopProperty);

    int imageX = (int)m_dCannonBulletLeft - (int)BunkerLeft;
    int imageY = (int)m_dCannonBulletTop - (int)BunkerTop;

    int TransformedY = yCoordinateToPixel(imageY, Bunker, wb);
    int TransformedX = xCoordinateToPixel(imageX, Bunker, wb);

    for (int y = TransformedY - 2; y < TransformedY + (int)m_dCannonBulletHeight + 2; y++)
    {
        for (int x = TransformedX; x < TransformedX + (int)m_dCannonBulletWidth; x++)
        {
            Windows.UI.Color color = wb.GetPixel(x, y);

            if (color.G == 253)
            {
                wb.SetPixel(x, y, Colors.Black);
                ret = true;
            }
        }
    }
    Bunker.Source = wb;
    return ret;
}

private int xCoordinateToPixel(int coordinate, Image Bunker, WriteableBitmap wb)
{
    double x;
    x = wb.PixelWidth / Bunker.ActualWidth * coordinate;
    return Convert.ToInt32(x);
}

private int yCoordinateToPixel(int coordinate, Image Bunker, WriteableBitmap wb)
{
    double y;
    y = wb.PixelHeight / Bunker.ActualHeight * coordinate;
    return Convert.ToInt32(y);
}

1 个答案:

答案 0 :(得分:5)

基本上可以运行,但是您需要注意几个“陷阱”:

  1. 如果在lock()unlock()调用之间的代码抛出异常(或使用returngoto关键字),则{{1 }}调用可能永远不会到达,因此您的互斥锁将无限期保持锁定。这可能会导致应用程序死锁,因为每个随后尝试锁定互斥锁的线程最终都将永远等待自己的unlock()调用返回。 (如果改为使用lock_guard / RAII方法,则此危险消失了,这就是为什么这样做是推荐的/更安全的方法)

  2. 如果lock()对象在仍然可以被其他线程访问的同时被删除,则可能会导致不确定的行为,因为线程所依赖的member-variable-mutex将会被破坏。 。 (避免这种情况的典型方法是确保所有线程在它们所依赖的互斥体被A之前被破坏了-或通过将互斥体移出对象并移入对象一些您可以保证不会在线程仍在运行时被销毁的高级对象)