gpt4 book ai didi

c++ - 如何使这段代码中的线程独立运行

转载 作者:太空狗 更新时间:2023-10-29 21:37:06 27 4
gpt4 key购买 nike

我是线程概念的新手,我试图更好地理解它们。阅读有关理论后,我决定用线程编写一个简单的程序。我在互联网上找到了这个(可能很简单)任务:

Write a program that calculates prime numbers and numbers of Fibunacci on different threads.

a. The first thread starts searching for prime number from 1, until killing of the program and when a prime number is found the program must present the time for finding this number.

b. The second thread is calculating and printing numbers of Fibunacci from 1 until killing of the program. When a new number of Fibunacci is found the program prints this number and the time for calculating this number.

c. The time is shown in ms (milliseconds)

d. Think about strategies for not having overlapping messages from the console.

e. The program must work with large as possible numbers. When the number is too large to be held in type like unsigned long long the program stops the calculation of that kind of numbers and shows error message.

Example output:

Prime 1, 0.1 ms.

Fibunacci 1, 0.1 ms.

Prime 2, 0.1 ms.

Fibunacci 2, 0.1 ms.

Prime 3, 0.1 ms.

Fibunacci 3, 0.1 ms.

Fibunacci 5, 0.1 ms.

Prime 5, 0.1 ms.

Fibunacci 8, 0.1 ms.

Prime 7, 0.1 ms.

Fibunacci 13, 0.2 ms.

Fibbunaci 21, 0.1 ms.

Prime 11, 0.2 ms.

这是我写的代码:

#include <iostream> // std::cout
#include <string> // std::cout << std::string
#include <thread> // std::thread
#include <time.h> // clock()
#include <mutex> // std::mutex

std::mutex mtx;
int timePrim, timeFib;

bool isPrime(int testedNumber)
{
if (testedNumber <= 2) return true;
if (testedNumber % 2 == 0) return false;
for (int i = 3; (i*i) <= testedNumber; i += 2)
{
if (testedNumber % i == 0) return false;
}
return true;
}

// the function is realized by a recursive algorithm; credits to stackoverflow ;)
bool isFibonacci(unsigned long long testedNumber, int a = 1, int b = 1)
{
if (testedNumber == 0 || testedNumber == 1)
return true;//returning true for 0 and 1 right away.
int nextFib = a + b;//getting the next number in the sequence
if (nextFib > testedNumber)
return false;//if we have passed the tested number, it's not in the sequence
else if (nextFib == testedNumber)
return true;//if we have a perfect match, the tested number is in the sequence
else
isFibonacci(testedNumber, b, nextFib);//otherwise, get the next fibonacci number and repeat.
}

void CheckNumber(unsigned long long numberToCheck, bool ifPrime)
{
bool result = false;
if (ifPrime == true)
{
result = isPrime(numberToCheck);
}
else
{
result = isFibonacci(numberToCheck);
}
if (result == true)
{
float currentTime = 0;
std::string typeNumber = "";
if (ifPrime == true)
{
typeNumber = "Prime";
currentTime = (float)(clock() - timePrim) / CLOCKS_PER_SEC;
timePrim = clock();
}
else
{
typeNumber = "Fibonacci";
currentTime = (float)(clock() - timeFib) / CLOCKS_PER_SEC;
timeFib = clock();
}
mtx.lock();
std::cout << typeNumber << " number " << numberToCheck << "; time " << currentTime << std::endl;
mtx.unlock();
}
}

int main()
{
timePrim = timeFib = clock();

for (unsigned long long i = 0; true; i++) // endless for loop == while(true) // by requirements
{
std::thread primeThread = std::thread(CheckNumber, i, true);
std::thread fibThread = std::thread(CheckNumber, i, false);
primeThread.join();
fibThread.join();
}

}

据我所知,这两个线程应该相互独立并以相关函数找到数字的速度打印结果。但是结果看起来很简单——按照主函数中 for 循环中迭代器前进的顺序而不是计算时间。这是来自控制台的片段:

Prime number 0; time 0.005

Fibonacci number 0; time 0.007

Prime number 1; time 0.03

Fibonacci number 1; time 0.029

Prime number 2; time 0.093

Fibonacci number 2; time 0.092

Prime number 3; time 0.023

Fibonacci number 3; time 0.023

Prime number 5; time 0.05

Fibonacci number 5; time 0.052

Prime number 7; time 0.023

Fibonacci number 8; time 0.045

Prime number 11; time 0.038

Prime number 13; time 0.077

Fibonacci number 13; time 0.091

Prime number 17; time 0.019

Prime number 19; time 0.179

Fibonacci number 21; time 0.208

Prime number 23; time 0.027

为了使独立线程运行,我应该在此代码中更正什么?我的错误在哪里?

//抱歉,如果上面的英文文本不好 - 这不是我的母语,所以我可能犯了一些错误...

最佳答案

现在您的程序为每个数字 i 创建线程,因此如果您计算素数和斐波那契数,其中 i 从 0 到 gazilion,它将创建和销毁 2 gazilions 线程。线程创建需要完成系统调用,并且在循环中这样做并不是特别快。

此外,您还让两个线程在提交更多工作之前相互等待。

这是你的程序在伪代码中的样子(与真实编程语言的任何相似之处纯属巧合):

def prime(i):
calculate one prime

def fibo(i):
calculate one fibo

for i from 0 to gazilion:
prime_thread = create_and_run_thread(prime, i) # expensive, runs gazilion times
fibo_thread = create_and_run_thread(fibo, i) # expensive, runs gazilion times

wait_for(prime_thread) # wait until single number is crunched
wait_for(fibo_thread) # wait until single number is crunched

destroy_thread(prime_thread)
destroy_thread(fibo_thread)

相反,您可以为每个任务创建 2 个永久线程并分别循环:

def prime():
for i from 0 to gazilion:
calculate one prime

def fibo():
for i from 0 to gazilion:
calculate one fibo


prime_thread = create_and_run_thread(prime) # expensive, but runs only once
fibo_thread = create_and_run_thread(fibo) # expensive, but runs only once

wait_for(prime_thread) # you only wait until gazilion is reached
wait_for(fibo_thread) # you only wait until gazilion is reached

destroy_thread(prime_thread) # runs oly once
destroy_thread(fibo_thread) # runs oly once

关于c++ - 如何使这段代码中的线程独立运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38411036/

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