问题在C中计算pthreads的线程函数

时间:2012-11-04 22:17:44

标签: c pthreads time.h

所以我在计算每个线程的线程函数的经过时间时遇到问题,我需要能够找到所有线程的总运行时间,但是它没有正确执行。 (见代码下面的输出)

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <math.h>
#include <time.h>

int numthread;
double x1;
double x2;
double h; 
double totalintegral;
int n;              //number of trapezoids
int localn;

double gnolock;
double gmute;
double gbusy;
double gsema;

double doTrapRule(double localx1, double localx2, double h, int localn);
double doFunction(double x);
void *threadCalc(void* threadid);

int main(int argc, char * argv[])
{
    int i;
    x1 = 0.0;
    x2 = 20.0;
    n = 200000;

    numthread = 10;

    pthread_t* threads = malloc(numthread*sizeof(pthread_t));

    h = (x2 - x1)/n;
    localn = n/numthread;

    for(i = 0; i < numthread; i++)
    {
        pthread_create(&threads[i], NULL, (void *) &threadCalc, (void*) i);
    }

    for(i = 0; i < numthread; i++)
    {
        pthread_join(threads[i], NULL);
    }

    printf("Trap rule result with %d trap(s) is %f\n", n, totalintegral);
    fflush(stdout);
    printf("no lock completed in %f\n", gnolock);
    exit(0);
}

void *threadCalc(void* threadid)
{
    clock_t start = clock();
    double localx1;
    double localx2; 
    double localintegral;
    int cur_thread = (int)threadid;

    localx1 = x1 + cur_thread * localn * h;
    localx2 = localx1 + localn * h;

    localintegral = doTrapRule(localx1, localx2, h, localn);

    totalintegral = totalintegral + localintegral;
    //printf("Trap rule result with %d trap(s) is %f", n, totalintegral);
    clock_t stop = clock();
    double time_elapsed = (long double)(stop - start)/CLOCKS_PER_SEC;
    printf("time elapsed of each thread %f\n",time_elapsed);
    gnolock = gnolock + time_elapsed;
    return NULL;
}


double doTrapRule(double localx1, double localx2, double h, int localn)
{
    //time start here
    double localtrapintegral;
    double tempx1;
    int i;

    localtrapintegral = (doFunction(localx1) + doFunction(localx2)) / 2.0;

    for(i = 1; i <= (localn - 1); i++)
    {
        tempx1 = localx1 + i * h;
        localtrapintegral = localtrapintegral + doFunction(tempx1);
    }

    localtrapintegral = localtrapintegral * h;
    //time end here, add elapsed to global
    return localtrapintegral;
}

double doFunction(double x)
{
    double result;
    result = x*x*x;

    return result;
}

输出:

time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
time elapsed of each thread 0.010000
time elapsed of each thread 0.010000
time elapsed of each thread 0.000000
time elapsed of each thread 0.000000
Trap rule result with 200000 trap(s) is 40000.000001
no lock completed in 0.020000

正如你所看到的那样,只有线程中的某个人实际上正在返回一个时间。我多次运行,每次只有几个线程返回结果。正如FYI gnolock是我的变量,它存储了经过的总时间。我猜测为什么这不起作用是因为小数点超出了范围,但它不应该是?

3 个答案:

答案 0 :(得分:2)

如果您在系统上拨打clock(),则其分辨率为10毫秒。因此,如果一个过程需要2毫秒,那么它通常会报告0.00s或0.01s的时间,具体取决于你无法控制的一堆东西。

使用其中一个高分辨率时钟代替。您可以将clock_gettimeCLOCK_THREAD_CPUTIME_IDCLOCK_PROCESS_CPUTIME_ID一起使用,我相信此时钟的分辨率比clock()好几个数量级。

有关详细信息,请参阅man 2 clock_gettime

答案 1 :(得分:1)

最有可能的是,您的时钟滴答对于您尝试测量的经过时间来说太粗糙了。大多数启动和停止时钟都是一样的。偶尔,在你的线程执行期间偶然发生时钟滴答,你会看到1滴答。 (这实际上是迪特里希上面所说的)。

作为这意味着什么的一个例子,假设你的线程需要一个小时才能完成,你的时钟每天午夜一次。大多数情况下,当你运行线程时,它是在同一天开始和结束。但如果您碰巧在午夜的一个小时内运行它,您将看到不同日期的开始和停止(1个刻度)。你需要的是一个更快的时钟,但这样的时钟可能无法使用。

答案 2 :(得分:0)

您使用的是错误的工具。 clock不衡量已用时间,但

  

clock()函数返回使用的处理器时间的近似值   通过该计划。

这是完全不同的两件事。也许你的线程不会耗费大量的处理器时间。