这个论坛中的任何人都可以在C中举例说明两个线程如何处理来自一个文本文件的数据。
例如,我有一个包含段落的文本文件。我有两个线程来处理所述文件中的数据。一个线程将计算段落中的行数。第二个线程将计算数字字符。
感谢
答案 0 :(得分:2)
如果您在C ++中询问我可以给您一个代码示例,但我很长时间没有完成ANSI C,所以我会给你设计和伪代码。
请记住,这是一个非常糟糕的伪代码,旨在举例说明。我不是在问你为什么要这样做。就我所知,它可能是一个有线程的运动,或者因为你“感觉就像”。
示例1
int integerCount = 0;
int lineCount = 0;
numericThread()
{
// By flagging the file as readonly you should
// be able to open it as many times as you wish
handle h = openfile ("textfile.txt". readonly);
while (!eof(h)) {
String word = readWord (h);
int outInteger
if (stringToInteger(word, outInteger)) {
++integerCount;
}
}
}
lineThread()
{
// By flagging the file as readonly you should
// be able to open it as many times as you wish
handle h = openfile ("textfile.txt". readonly);
while (!eof(h)) {
String word = readWord (h);
if (word.equals("\n") {
++lineCount ;
}
}
}
如果由于某种原因你无法在readonly中打开文件两次,则需要为每个线程维护一个队列,让主线程将字放入每个线程队列中。然后线程将从队列中拉出来。
示例2
int integerCount = 0;
int lineCount = 0;
queue numericQueue;
queue lineQueue;
numericThread()
{
while (!numericQueue.closed()) {
String word = numericQueue.pop();
int outInteger
if (stringToInteger(word, outInteger)) {
++integerCount;
}
}
}
lineThread()
{
while (!lineQueue.closed()) {
String word = lineQueue.pop();
if (word.equals("\n") {
++lineCount ;
}
}
}
mainThread()
{
handle h = openfile ("textfile.txt". readonly);
while (!eof(h)) {
String word = readWord(h);
numericQueue.push(word);
lineQueue.push(word);
}
numericQueue.close();
lineQueue.close();
}
答案 1 :(得分:2)
有很多方法可以做到这一点。您可以根据您希望的速度或简单或优雅或过度设计来做出不同的设计决策。 Andrew Finnell发布的一种方法是让每个线程打开文件并完全独立地读取它。理论上这并不是很好,因为你做了两次昂贵的IO,但实际上它可能很好,因为操作系统可能已经缓存了先读取执行的内容。 Double IO仍然比平均价格贵,因为它涉及大量不必要的系统调用,但实际上除非你有一个非常大的文件,否则它将无关紧要。
如何执行此操作的另一个模型是每个线程具有输入队列或共享全局队列。主线程读取文件并将每一行依次放在队列中,并且主线程可能会成为您的一个工作线程。这更复杂,因为必须同步对队列的访问,或者必须使用某些无锁队列实现。在共享全局队列的情况下,数据重复较少,但现在该数据的生命周期更复杂。
只是要指出这么简单的事情有多少种方法,你可以去过度工程路线并使每个线程都是通用的。不是将数据放在队列上,而是放置数据(或指向数据的指针)和函数指针,让每个线程执行回调。这种模型可能会感觉你是否计划添加更多类型的东西来计算,但是想限制你将使用的线程数。
答案 2 :(得分:0)
我不认为使用2个线程而不是一个线程会看到很多性能差异。无论哪种方式,您都不希望两个线程都读取该文件。首先读取文件,然后将流的COPY传递给您想要的方法并处理它们。线程无法同时访问相同的数据流,因此您需要使用2个文本文件副本。
P.S。根据文件的大小,您可能会使用2个线程来放松性能。