如何使此代码中的线程独立运行

How to make the threads in this code to go independently

本文关键字:线程 独立 运行 何使此 代码      更新时间:2023-10-16

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

编写一个计算素数和Fibunacci数的程序 在不同的线程上。

一个。 第一个线程从 1 开始搜索质数,直到 杀死程序,当找到质数时,程序 必须提供查找此号码的时间。

二. 第二个线程是计算和打印 Fibunacci 的数字 从 1 到程序被杀。当新的菲布纳奇数是 发现程序打印此数字和计算时间 数。

三. 时间以毫秒(毫秒)为单位显示

d. 考虑一下没有来自 安慰。

e. 该程序必须使用尽可能大的数字。当 数字太大,无法像无符号长长这样的类型保存 程序停止计算这种数字并显示错误 消息。

示例输出:

质数 1,0.1 毫秒

菲布纳奇 1,0.1 毫秒

质数 2,0.1 毫秒

菲布纳奇 2,0.1 毫秒

质数 3,0.1 毫秒

菲布纳奇 3,0.1 毫秒

菲布纳奇 5, 0.1 毫秒

素数 5,0.1 毫秒

菲布纳奇 8, 0.1 毫秒

质数 7,0.1 毫秒

菲布纳奇 13, 0.2 毫秒

菲布纳奇 21, 0.1 毫秒

质数 11,0.2 毫秒

这是我写的代码:

#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 循环中的前进顺序,而不是按计算时间。这是控制台中的一个代码片段:

质数 0;时间 0.005

斐波那契数 0;时间 0.007

质数 1;时间 0.03

斐波那契数1;时间0.029

质数 2;时间 0.093

斐波那契数2;时间0.092

质数 3;时间 0.023

斐波那契数3;时间0.023

质数 5;时间 0.05

斐波那契数5;时间0.052

质数 7;时间 0.023

斐波那契数8;时间0.045

质数 11;时间 0.038

质数 13;时间 0.077

斐波那契数13;时间0.091

质数 17;时间 0.019

质数19;时间0.179

斐波那契数21;时间0.208

质数 23;时间 0.027

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

对不起,如果上面的英文文字不好 - 这不是我的母语,所以我可能犯了一些错误......

现在你的程序为每个数字i创建线程,所以如果你计算素数和斐波那契,其中i从0到gilion,它将创建和破坏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

创建两个std::thread对象的向量。一个用于斐波那契计算,一个用于素数计算。然后有两个循环:一个用于创建两个线程并将它们添加到向量中,另一个循环用于连接向量中的所有线程。

当第二个循环等待第一个线程退出时,在第一个循环中创建的所有线程都将并行运行。


您现在要做的是创建两个线程,然后立即等待它们结束,然后再在循环中迭代。这意味着一次只有一个斐波那契和一个素数线程。