【发布时间】:2023-02-17 04:09:08
【问题描述】:
首先,我完全是 C++ 的初学者,这就是为什么如果这个问题可能很愚蠢(或者可能没有任何意义),我深表歉意,但我完全不知道在我的情况下我能做什么。
所以,我最近一直在尝试学习多线程,因为我认为使用线程而不是在整个大内容(即文件的内容)上运行的简单循环来获得更好的方法实际上速度更快。
这是我实际拥有的代码(不完整,但在这种情况下并不重要):
int end = 40000;
std::string content; // this variable is filled before calling the function "another_function", don't mind it
// this function is completely useless, this is just for testing purposes
void dummy_function(int *idx, int value_to_divide) {
std::list<int> test;
for (; *idx <= ending / div; *idx++) {
int count = 100 + *i;
test.insert(test.end(), { 1, 2, 3, count });
std::cout << content.c_str() + *i << endl;
test.clear();
}
}
void another_function() {
int idx = 0;
std::vector<std::thread> th;
for (int j = 4; j != 0; j--) {
th.push_back(std::thread(&dummy_function, &idx + ((j != 4) ? (end / (j + 1)) : 0), j));
}
for (auto& thread:th)
thread.join();
}
我如何看待我所做的是我将内容变量的读取分成 4 个线程(使它们同时停止,因为它们应该具有相同的长度),第一个从 0(开始)开始,第二个一个开始于 (i + (end / 3)), 等等...
但是,当第一个线程停止时它会发生段错误,实际上其他线程甚至没有从我认为它们会开始的地方开始,所以也许我一开始甚至不理解线程的概念(正如我所说的我是一个这个大声笑的初学者)。
我听说过一种叫做“安全队列”或“安全线程”的东西(使用互斥锁和相关的东西),但我似乎不明白如何在我的案例中使用它。
有人能够解释我如何让这些线程并行运行并且“安全地”运行吗?
谢谢 :)
【问题讨论】:
-
有一本书《C++ 并发实战》
-
如果你是 C++ 的初学者,那么在深入线程之前先了解更多 C++,至少了解:std::thread、std::async、std::mutex、std::scoped_lock、std::condition_variable、lambda 函数和他们的俘虏。并且知道线程也是有代价的,仅仅在一个问题上投入 n 个线程不会让它运行得快 n 倍,并且代码的复杂性也会增加。有关我提到的类的更多信息,请查看 cppreference。 (最后你也只需要积累经验)
-
如果您真的是一个完全的初学者,您可能不应该使用多线程编写代码;他们可能很棘手。先把基础打好,再做更复杂的事情。
-
好吧,我相信实践总比什么都不做要好,因为我必须从某个地方开始,但是是的,你们都是对的(即使我会学习 Pepijin 所说的一切,我至少想知道为什么会出现段错误哈哈)
-
由于丑陋的行
&idx + ((j != 4) ? (end / (j + 1)) : 0),它肯定会导致段错误。我不知道你想用它做什么,但这会导致一个错误的指针,因此稍后取消引用它会导致未定义的行为,这在实践中可能是一个段错误。首先尝试编写没有线程的代码,因为这个问题不是由于线程引起的。此外,请注意链表通常很慢,因此尝试使用多线程来加速此类代码当然不是最佳选择:首先考虑优化顺序代码(尤其是对于基于 IO 的代码)。
标签: c++ multithreading thread-safety