cygwin pthread_mutex_timedlock代理 [英] cygwin pthread_mutex_timedlock surrogate

查看:215
本文介绍了cygwin pthread_mutex_timedlock代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不幸的是cygwin GCC 4.5.3 pthread库实现不支持POSIX标准函数

Unfortunately the cygwin GCC 4.5.3 pthread library implementation doesn't support the POSIX standard function

int pthread_mutex_timedlock(pthread_mutex_t* mutex, struct timespec* abstime);



。可以使用 pthread_mutex_trylock()与(基于毫秒) nanosleep()调用?
我对后面的想法没有好的感觉,但无论如何,C ++实现可能看起来像这样:

Has anyone a good idea how to implement a good workaround for this method in a mutex wrapper class? May be using pthread_mutex_trylock() with a (milliseconds based) nanosleep() call? I don't have a good feeling about the latter idea, but anyway the C++ implementation could look like this:

bool MyPosixMutexWrapper::try_lock(const TimeDuration<>& timeout)
{
    if(valid)
    {
        if(timeout == TimeDuration<>::Zero)
        {
             if(pthread_mutex_trylock(&mutexHandle) == 0)
             {
                 return true;
             }
        }
        else
        {
            struct timespec now;
            clock_gettime(CLOCK_REALTIME,&now);
            TimeDuration<> tnow(now);
            tnow += timeout;
            struct timespec until = tnow.getNativeValue();
#if defined(_POSIX_TIMEOUTS)
            if(pthread_mutex_timedlock(&mutexHandle,&until) == 0)
            {
                return true;
            }
#else
            long milliseconds = timeout.milliseconds();
            while(milliseconds > 0)
            {
                 if(pthread_mutex_trylock(&mutexHandle) == 0)
                 {
                     return true;
                 }

                 struct timespec interval;
                 struct timespec remaining;
                 interval.tv_sec = 0;
                 interval.tv_nsec = 1000000;
                 do
                 {
                     remaining.tv_sec = 0;
                     remaining.tv_nsec = 0;
                     if(nanosleep(&interval,&remaining) < 0)
                     {
                         if(errno == EINTR)
                         {
                             interval.tv_sec = remaining.tv_sec;
                             interval.tv_nsec = remaining.tv_nsec;
                         }
                         else
                         {
                             return false;
                         }
                     }
                     clock_gettime(CLOCK_REALTIME,&now);
                     tnow = TimeDuration<>(now);
                     if(tnow >= TimeDuration(until))
                     {
                          return pthread_mutex_trylock(&mutexHandle) == 0;
                     }
                } while(remaining.tv_sec > 0 || remaining.tv_nsec > 0);
                --milliseconds;
            }
#endif
        }
    }
    return pthread_mutex_trylock(&mutexHandle) == 0;
}

有没有人对这个代码有更好的想法或改进?

Does anyone have a better idea or improvments for this code?

推荐答案

我的建议是使用 pthread_cond_timedwait 来模拟你的计时锁。这里的诀窍是 timed_mutex _ 从不持有很长时间,因为等待 timed_cond _ 释放锁。 timed_mutex _ 也会在 locked _ 设置或取消设置后立即释放。

My suggestion would be to use a pthread_cond_timedwait to mimic your timed lock. The trick here is that timed_mutex_ is never held for very long, since waiting on timed_cond_ releases the lock. timed_mutex_ is also released immediately after locked_ is set or unset.

struct MutexGuard {
    pthread_mutex_t &mutex_;
    MutexGuard (pthread_mutex_t &m) : mutex_(m) {
        pthread_mutex_lock(&mutex_);
    }
    ~MutexGuard () {
        pthread_mutex_unlock(&mutex_);
    }
};

struct TimedMutex {
    pthread_mutex_t timed_mutex_;
    pthread_cond_t timed_cond_;
    bool locked_;

    TimedMutex ()
        : timed_mutex_(), timed_cond_(), locked_(false) {
        pthread_mutex_init(&timed_mutex_, 0);
        pthread_cond_init(&timed_cond_, 0);
    }

    ~TimedMutex () {
        pthread_cond_destroy(&timed_cond_);
        pthread_mutex_destroy(&timed_mutex_);
    }

    int lock (const struct timespec *t) {
        MutexGuard g(timed_mutex_);
        while (locked_) {
            int r = pthread_cond_timedwait(&timed_cond_, &timed_mutex_, t);
            if (r < 0) return r;
        }
        locked_ = true;
        return 0;
    }

    void lock () {
        MutexGuard g(timed_mutex_);
        while (locked_) {
            pthread_cond_wait(&timed_cond_, &timed_mutex_);
        }
        locked_ = true;
    }

    void unlock () {
        MutexGuard g(timed_mutex_);
        locked_ = false;
        pthread_cond_signal(&timed_cond_);
    }
};

这篇关于cygwin pthread_mutex_timedlock代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆