C :将螺纹传递到功能异常
C++ : Passing threadID to function anomaly
我实现了一个并发队列,并使用两种方法: add (enqueue)&删除(Dequeue)。
要使用2个线程测试我的实现,我以一种称为getrandom()的方法在0和1之间生成了10(number_of_operations)。这使我可以创建添加和删除操作的不同分布。
dowork 方法将线程数量完成的工作分开。
问题:我从主函数传递的螺纹ID与Dowork方法接收到的螺纹ID不匹配。这是一些示例运行:
输出1
输出2
#define NUMBER_OF_THREADS 2
#define NUMBER_OF_OPERATIONS 10
int main () {
BoundedQueue<int> bQ;
std::vector<double> temp = getRandom();
double* randomNumbers = &temp[0];
std::thread myThreads[NUMBER_OF_THREADS];
for(int i = 0; i < NUMBER_OF_THREADS; i++) {
cout << "Thread " << i << " created.n";
myThreads[i] = std::thread ( [&] { bQ.doWork(randomNumbers, i); });
}
cout << "Main Threadn";
for(int i = 0; i < NUMBER_OF_THREADS; i++) {
if(myThreads[i].joinable()) myThreads[i].join();
}
return 0;
}
template <class T> void BoundedQueue<T>::doWork (double randomNumbers[], int threadID) {
cout << "Thread ID is " << threadID << "n";
srand(time(NULL));
int split = NUMBER_OF_OPERATIONS / NUMBER_OF_THREADS;
for (int i = threadID * split; i < (threadID * split) + split; i++) {
if(randomNumbers[i] <= 0.5) {
int numToAdd = rand() % 10 + 1;
add(numToAdd);
}
else {
int numRemoved = remove();
}
}
}
在这一行中,您是通过参考来捕获i
的:
myThreads[i] = std::thread ( [&] { bQ.doWork(randomNumbers, i); });
这意味着,当另一个线程运行lambda时,它将获得i的最新值,而不是创建时值。取而代之的是捕获它:
myThreads[i] = std::thread ( [&, i] { bQ.doWork(randomNumbers, i); });
更糟糕的是,当您未订购并写入i
时,您当前的代码具有未定义的行为。事实 i 可能在另一个线程读取它之前可能已经超出了主线程的范围。以上解决方案解决了所有这些问题。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 从构造函数抛出异常时如何克服内存泄漏
- C++中"覆盖功能的异常规范比基本版本更宽松"的奇怪错误
- 使用 stoi 功能进行异常处理
- 出乎意料的堆损坏在功能中发生在异常处理中
- C :将螺纹传递到功能异常
- 覆盖功能的异常规范比基本版本更宽松
- 所有OpenCV功能是否会引发异常
- 使功能异常安全
- QT/C++类型的异常过载功能情况
- 异常规范在声明和功能实现方面不兼容