gpt4 book ai didi

c++ - 另一个线程的调试实例改变了我的数据

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:00:52 26 4
gpt4 key购买 nike

我有一个庞大的全局结构数组。数组的某些区域与单独的线程相关联,并且这些线程可以修改它们的数组区域而无需使用临界区。但是数组中有一个特殊区域,所有线程都可以访问。访问数组这些部分的代码需要小心使用临界区(每个数组元素都有自己的临界区),以防止两个线程同时写入结构的任何可能性。

现在我有一个神秘的 bug,我正试图追踪它,它的发生是不可预测的,而且发生的频率非常低。似乎其中一个结构被一些不正确的数字填充。一个明显的解释是另一个线程意外地被允许设置这个数字,而它应该被排除在外。

不幸的是,跟踪这个错误似乎几乎是不可能的。每次出现坏数据的数组元素都不一样。我希望能够做的是为错误设置某种陷阱,如下所示:我将进入数组元素 N 的临界区,然后我知道没有其他线程应该能够触及数据,然后(直到我退出关键部分)为调试工具设置某种标志,说“如果任何其他线程试图更改此处的数据,请中断并向我显示有问题的源代码补丁”......但我怀疑不存在这样的工具。 .. 或者是吗?或者我应该采用一些完全不同的调试方法。

最佳答案

用一个透明的互斥类包装你的数据怎么样?然后您可以应用额外的锁定状态检查。

class critical_section;

template < class T >
class element_wrapper
{
public:
element_wrapper(const T& v) : val(v) {}
element_wrapper() {}
const element_wrapper& operator = (const T& v) {
#ifdef _DEBUG_CONCURRENCY
if(!cs->is_locked())
_CrtDebugBreak();
#endif
val = v;
return *this;
}
operator T() { return val; }
critical_section* cs;
private:
T val;
};

至于关键部分的实现:

class critical_section
{
public:
critical_section() : locked(FALSE) {
::InitializeCriticalSection(&cs);
}
~critical_section() {
_ASSERT(!locked);
::DeleteCriticalSection(&cs);
}
void lock() {
::EnterCriticalSection(&cs);
locked = TRUE;
}
void unlock() {
locked = FALSE;
::LeaveCriticalSection(&cs);
}
BOOL is_locked() {
return locked;
}
private:
CRITICAL_SECTION cs;
BOOL locked;
};

实际上,除了自定义 critical_section::locked 标志,还可以使用 ::TryEnterCriticalSection(如果成功,后面跟着 ::LeaveCriticalSection ) 以确定是否拥有关键部分。不过,上面的实现几乎一样好。

所以适当的用法是:

typedef std::vector< element_wrapper<int> > cont_t;

void change(cont_t::reference x) { x.lock(); x = 1; x.unlock(); }

int main()
{
cont_t container(10, 0);

std::for_each(container.begin(), container.end(), &change);
}

关于c++ - 另一个线程的调试实例改变了我的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2461924/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com