【问题标题】:Does a portable pthread_sleep() function exist?是否存在可移植的 pthread_sleep() 函数?
【发布时间】:2021-02-02 08:33:01
【问题描述】:

我正在编写一个将在 Linux 和 Windows 上构建的 ANSI C 应用程序。

我为 Windows 构建了 pthread 2.9.1 库,一切正常。

问题是我找不到函数:pthread_sleep()

我也四处寻找该功能,但它似乎不存在。

如果没有该函数,我的代码将不得不在 Windows 上调用 Sleep(),在 Linux 上调用 sleep(),但这正是我不想要的。

谢谢, 恩里科·米廖雷

【问题讨论】:

  • 如果你需要你的线程休眠,你不应该使用线程。

标签: c pthreads sleep


【解决方案1】:

问题是我找不到函数:pthread_sleep()

不,你不会,因为 pthreads 不提供这样的功能。为什么会这样? pthreads API 没有任何关于使线程休眠的特定内容,真正的 POSIX 平台都有各种其他机制,包括sleep(),可以使线程休眠。无论如何,让多线程程序的线程休眠(与 block 相对)并不是一件好事或合理的事情。

如果没有该函数,我的代码将不得不在 Windows 上调用 Sleep(),在 Linux 上调用 sleep(),但这正是我不想要的。

我倾向于认为您也不想调用与平台无关的替代方案。但是,处理使用各种特定于平台的函数来完成共同目标的此类问题的传统方法是使用条件定义的宏或具有条件定义的实现的包装函数来隐藏特定于平台的位。例如,

#if defined(_MSC_VER)
// Sleep() expects an argument in milliseconds
#define SLEEP(time) Sleep((time) * 1000)
#else
// sleep() expects an argument in seconds
#define SLEEP(time) sleep(time)
#endif

但是,对于您的特定情况,也有可能调用具有用户可指定超时的函数,您希望该超时总是过期。 Pthreads 确实提供了您可以使用的函数,例如pthread_cond_timedwait()。您可以使用它编写一个睡眠函数,而无需任何条件编译。例如,

int my_sleep(long milliseconds) {
    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
    int rval = 0;

    if (milliseconds > 0) {
        struct timespec time;

        rval = timespec_get(&time, TIME_UTC);
        // ... handle any error ...
        time.tv_nsec += (milliseconds % 1000) * 1000000;
        time.tv_sec += milliseconds / 1000 + time.tv_nsec / 1000000;
        time.tv_nsec %= 1000000;

        rval = pthread_mutex_lock(&mutex);
        if (rval != 0) {
            // handle error ...
        } else {
            // The loop handles spurrious wakepups
            do {
                rval = pthread_cond_timedwait(&cond, &mutex, &time);  // expects ETIMEDOUT
            } while (rval == 0);
            if (rval != ETIMEDOUT) {
                // handle error ...
            }
            rval = pthread_mutex_unlock(&mutex);  // THIS MUST NOT BE SKIPPED
            // ... handle any error ...
        }
    }

    return rval;
}

【讨论】:

  • 感谢您的回答。我将测试您提出的功能:my_sleep()
猜你喜欢
  • 1970-01-01
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多