多线程不像预期的那样行动
Multi-threading not acting as expected
我正在编写一个c 程序,该程序接收文件输入并计算某些字符发生的次数。具体来说,我想使用多线程来解决此问题,以获得多线程的经验。但是,我每次执行都会收到不同的结果,并且想知道我可能会出错的地方 - 仍在学习C 。任何意见将是有益的。
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <fstream>
#include <bits/stdc++.h>
#define NUM_THREADS 5
const char flag = 'w';
int totalSum = 0;
bool matchesFlag(char letter) {
return letter == flag;
}
void *processText(void *threadArg) {
std::string text = *static_cast<std::string*>(threadArg);
totalSum += std::count_if(text.begin(), text.end(), matchesFlag);
pthread_exit(NULL);
}
int main() {
std::ifstream inFile;
pthread_t threads[NUM_THREADS];
inFile.open("text.txt");
std::string line;
while (inFile.good()) {
getline(inFile, line);
int created = -1;
while (created) {
for (int i = 0; i < NUM_THREADS && created != 0; ++i) {
created = pthread_create(&threads[i], NULL, processText, (void *)&line);
}
}
}
std::cout << totalSum << std::endl;
return 0;
}
所以,让我们看一下到目前为止写的问题和评论。
stackoverflow提出的,我们应该是新成员并遵循行为准则。
。然后我们应该尝试提供帮助。
首先评论:
您不使用std ::线程的原因吗? - 2785528
好吧,可能有很多原因。也许BOPAS2使用C 98。也许他是Linux低级爱好者。也许,BOPAS2是C 编程的新手,并且想学习和理解。无论如何,这只是一个示例代码。
我的提议是:如果有C 11(或更高版本(的编译器,则应使用此功能,您应该开始学习新的C 线程功能。
下一个评论
我看到所示代码至少有四个基本问题。按照设计,显示的代码无法正确同步多个线程,更不用说启动四个线程的原因到底是什么,其目的是在每行中计数相同的字母,因此希望获得最终数量的四倍,这是四倍但是由于缺乏同步和原子性,最终结果将是完全随机的,更不用说std :: string将脱离范围并在这些线程完成之前被销毁,导致行为不确定,并随机崩溃。 - Sam Varshavchik
是的,确实存在此代码中的问题。但是,如果您查看代码,则每行只有一个线程。只要失败并且PTHREAD_CREATE返回-1,它将尝试5次。如果PTHREAD_CREATE成功,它将返回0,并且循环将终止。很可能,PTHREAD_CREATE将始终成功,将线程句柄始终覆盖并在线程的数组位置0中。覆盖不好,但在此示例中不会损害。因为pthread_create的结果将在以后不会使用。关于我的理解,无需同步任务(例如与JOIN或其他任何任务(:也不是问题。当它超出范围时,std ::字符串不是问题。STD :: String Line有一个本地副本(螺纹局部变量(。由于上述内容,永远不会随机崩溃。
下一个评论
为什么要为文件的每一行创建5个线程,这些线程都重复每行相同的任务?你到底是什么?
这是一个错误的陈述。每个读行只有一个线程。如果有多行,则启动了多个线程。然而。我不建议使用这种错误处理/恢复策略。
最后评论
建议 - 确保您阅读了有关此主题的大量文献,并在开始之前了解了良好的样本程序。学习如何正确编写MT程序不应通过反复试验来完成。MT编程不仅仅涉及学习如何启动线程
这是真的。多任务是最复杂的,需要大量阅读,实践和长期的理解。大多数认为自己正在理解多线程的人,根本不知道。我都不是。
但是每个人都需要开始。。。
我对问题的分析和回答是(我不确定(:
线程函数的启动以及线程函数参数threadarg的本地副本,可能比读取下一行。这意味着,可以在读取下一行之后复制该变量。而且由于使用指针,因此可能会产生影响。因此,在一个测试中,可以正确解释一条线,并且在下一个运行中可以延迟阅读。这将导致不同的结果。
第二个问题是" Totalsum ="。在这里,我们进行阅读(没问题(和写作。可能有一个所谓的种族状况。2个线程试图访问相同的全局变量。然后在分配过程中进行胎面变化,在该分配中,可以使用两次旧的Vaible。但是在这里,我不确定,比我更专业的人需要判断。
,但一般规则是:如果您像示例中的示例中写入全局变量,请在此操作过程中保护线程更改。有不同的方法。最常见的是使用静音(在这里我不能对所有这些都详细介绍(或关键部分,锁或条件变量或STD :: Atomic或您提供的操作系统提供的任何内容。
重要的是,您甚至可以防止将变量写两次的可能性。在大多数情况下,应避免全局变量。
也许阅读此内容会给您更多的见解。
我希望我至少可以帮助一点。
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 如何阻止TensorFlow的多线程
- 如何在多线程中正确使用unique_ptr进行多态性?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 多线程比没有线程C++慢
- 具有 C++11 多线程的特征库
- 通过安装信号处理程序关闭多线程应用程序
- 成员变量在多线程 C++ 时自行更改
- 尝试从头开始实现Leetcode的FizzBuzz多线程问题。收到"libc++abi.dylib: terminating"错误