首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在使用线程时测量执行时间

在使用线程时测量执行时间
EN

Stack Overflow用户
提问于 2019-05-16 22:08:48
回答 3查看 909关注 0票数 1

我想测量一些代码的执行时间。代码在main()函数中开始,在事件处理程序中结束。

我有一个看起来像这样的C++11代码:

代码语言:javascript
运行
复制
#include <iostream>

#include <time.h>

...

volatile clock_t t;

void EventHandler()
{
    // when this function called is the end of the part that I want to measure
    t = clock() - t;
    std::cout << "time in seconds: " << ((float)t)/CLOCKS_PER_SEC;
}

int main()
{
    MyClass* instance = new MyClass(EventHandler); // this function starts a new std::thread
    instance->start(...); // this function only passes some data to the thread working data, later the thread will call EventHandler()
    t = clock();
    return 0;
}

因此,可以保证EventHandler()只会被调用一次,而且只会在instance->start()调用之后调用。

它正在工作,这段代码给了我一些输出,但它是一个可怕的代码,它使用全局变量,并且不同的线程访问全局变量。然而,我不能改变使用的API (构造函数,线程调用EventHandler的方式)。

我想问一下,是否有更好的解决方案。

谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-05-16 23:13:40

全局变量是不可避免的,只要MyClass需要一个普通的函数,并且没有办法将一些上下文指针与函数一起传递...

不过,您可以以一种稍微更整洁的方式编写代码:

代码语言:javascript
运行
复制
#include <future>
#include <thread>
#include <chrono>
#include <iostream>

struct MyClass
{
    typedef void (CallbackFunc)();

    constexpr explicit MyClass(CallbackFunc* handler)
     : m_handler(handler)
    {
    }

    void Start()
    {
        std::thread(&MyClass::ThreadFunc, this).detach();
    }

private:
    void ThreadFunc()
    {
        std::this_thread::sleep_for(std::chrono::seconds(5));
        m_handler();
    }

    CallbackFunc*     m_handler;
};


std::promise<std::chrono::time_point<std::chrono::high_resolution_clock>>   gEndTime;

void EventHandler()
{
    gEndTime.set_value(std::chrono::high_resolution_clock::now());
}


int main()
{
    MyClass         task(EventHandler);

    auto            trigger = gEndTime.get_future();
    auto            startTime = std::chrono::high_resolution_clock::now();
    task.Start();
    trigger.wait();

    std::chrono::duration<double>   diff = trigger.get() - startTime;

    std::cout << "Duration = " << diff.count() << " secs." << std::endl;

    return 0;
}
票数 1
EN

Stack Overflow用户

发布于 2019-05-16 22:46:41

clock()调用不会过滤出调度器与程序事件处理程序线程并行运行的不同进程和线程的执行。还有像time ()和getrusage()这样的替代方法,它们告诉cpu进程的时间。虽然没有明确提到这些调用的线程行为,但如果是Linux,线程将被视为进程,但必须对其进行调查。

票数 0
EN

Stack Overflow用户

发布于 2019-05-16 23:03:55

clock()在这里是错误的工具,因为它不计算CPU实际运行您的操作所需的时间,例如,如果线程根本没有运行,时间仍然会被计算在内。

相反,您必须使用特定于平台的API,比如用于POSIX兼容系统的pthread_getcpuclockid (检查是否定义了_POSIX_THREAD_CPUTIME ),它计算特定线程实际花费的时间。

您可以查看我为C++编写的支持线程感知测量的benchmarking library (请参阅struct thread_clock实现)。

或者,您可以使用man page中的代码片段

代码语言:javascript
运行
复制
/* Link with "-lrt" */

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>

#define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)

#define handle_error_en(en, msg) \
        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void *
thread_start(void *arg)
{
    printf("Subthread starting infinite loop\n");
    for (;;)
        continue;
}

static void
pclock(char *msg, clockid_t cid)
{
    struct timespec ts;
    printf("%s", msg);
    if (clock_gettime(cid, &ts) == -1)
        handle_error("clock_gettime");
    printf("%4ld.%03ld\n", ts.tv_sec, ts.tv_nsec / 1000000);
}

int
main(int argc, char *argv[])
{
    pthread_t thread;
    clockid_t cid;
    int j, s;

    s = pthread_create(&thread, NULL, thread_start, NULL);
    if (s != 0)
        handle_error_en(s, "pthread_create");

    printf("Main thread sleeping\n");
    sleep(1);

    printf("Main thread consuming some CPU time...\n");
    for (j = 0; j < 2000000; j++)
        getppid();

    pclock("Process total CPU time: ", CLOCK_PROCESS_CPUTIME_ID);

    s = pthread_getcpuclockid(pthread_self(), &cid);
    if (s != 0)
        handle_error_en(s, "pthread_getcpuclockid");

    pclock("Main thread CPU time:   ", cid);

    /* The preceding 4 lines of code could have been replaced by:
    pclock("Main thread CPU time:   ", CLOCK_THREAD_CPUTIME_ID); */

    s = pthread_getcpuclockid(thread, &cid);
    if (s != 0)
        handle_error_en(s, "pthread_getcpuclockid");
    pclock("Subthread CPU time: 1    ", cid);

    exit(EXIT_SUCCESS);         /* Terminates both threads */
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56170540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档