pthread_mutex_timedlock - ожидание в миллисекундах
От: vdmz  
Дата: 28.10.12 17:16
Оценка:
Возможно ли используя ф-цию pthread_mutex_timedlock задать время ожидания в миллисекундах? Если да, тогда как обойти возможное переполнение?
Re: pthread_mutex_timedlock - ожидание в миллисекундах
От: ДимДимыч Украина http://klug.org.ua
Дата: 28.10.12 18:08
Оценка:
Здравствуйте, vdmz, Вы писали:

V>Возможно ли используя ф-цию pthread_mutex_timedlock задать время ожидания в миллисекундах? Если да, тогда как обойти возможное переполнение?


Возможно, конечно. В tv_nsec помещать сумму по модулю 1E9, к tv_sec — частное от суммы по тому же модулю.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[2]: pthread_mutex_timedlock - ожидание в миллисекундах
От: vdmz  
Дата: 28.10.12 18:11
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, vdmz, Вы писали:


V>>Возможно ли используя ф-цию pthread_mutex_timedlock задать время ожидания в миллисекундах? Если да, тогда как обойти возможное переполнение?


ДД>Возможно, конечно. В tv_nsec помещать сумму по модулю 1E9, к tv_sec — частное от суммы по тому же модулю.


ДимДимыч, угости примером?
Re[3]: pthread_mutex_timedlock - ожидание в миллисекундах
От: ДимДимыч Украина http://klug.org.ua
Дата: 28.10.12 18:35
Оценка: 3 (1)
Здравствуйте, vdmz, Вы писали:

V>ДимДимыч, угости примером?


Ну, например, без оптимизационных извращений
  struct timespec ts;
  long ns;
…
  clock_gettime(CLOCK_MONOTONIC, &ts);

  ns = ts.tv_nsec + ms * 1000 * 1000;
  ts.tv_nsec = ns % (1000 * 1000 * 1000);
  ts.tv_sec += ns / (1000 * 1000 * 1000);
…


При 32-разрядном long позволяет гарантированно задавать таймаут до ≈ 2000 мс.

Вызов clock_gettime() для случая, если в аттрибутах мютекса также указано использование CLOCK_MONOTONIC. В ином случае clock_gettime() нужно вызывать с соответствующим аргументом.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[4]: pthread_mutex_timedlock - ожидание в миллисекундах
От: vdmz  
Дата: 28.10.12 19:52
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, vdmz, Вы писали:


V>>ДимДимыч, угости примером?


ДД>Ну, например, без оптимизационных извращений

ДД>
ДД>  struct timespec ts;
ДД>  long ns;
ДД>…
ДД>  clock_gettime(CLOCK_MONOTONIC, &ts);

ДД>  ns = ts.tv_nsec + ms * 1000 * 1000;
ДД>  ts.tv_nsec = ns % (1000 * 1000 * 1000);
ДД>  ts.tv_sec += ns / (1000 * 1000 * 1000);
ДД>…
ДД>


ДД>При 32-разрядном long позволяет гарантированно задавать таймаут до ≈ 2000 мс.


ДД>Вызов clock_gettime() для случая, если в аттрибутах мютекса также указано использование CLOCK_MONOTONIC. В ином случае clock_gettime() нужно вызывать с соответствующим аргументом.




class CMutex
{
public:
pthread_mutex_t m;
CMutex();
~CMutex();
int fnWaitForMutex(long time);
};
 
CMutex::CMutex()
{
    // Use the mutex attribute to create the mutex
    if (0 != pthread_mutex_init(&m, NULL))
    {
        //lf
    }
}

CMutex::~CMutex()
{
    // Mutex attribute can be destroy after initializing the mutex variable
    if (0 != pthread_mutex_destroy (&m))
    {
        //lf
    }
}

int CMutex::fnWaitForMutex(long time)
{
    struct timeval now;
    struct timespec timeout;

    gettimeofday(&now, NULL);
    uint usec = (time % 1000)*1000 + now.tv_usec;
    timeout.tv_sec = now.tv_sec + time/1000 + usec/1000000;
    timeout.tv_nsec = (usec % 1000000)*1000;

    return pthread_mutex_timedlock(&m, &timeout);
}

int main()
{
    CMutex mutex;
    printf("\n 1");
    mutex.fnWaitForMutex(5000);
    printf("\n 2");
    printf("\n 3");
    printf("\n 4");
    mutex.fnWaitForMutex(5000);
    printf("\n 5");
    return 0;
}



Есть небольшой класс для проверки мутекса с задержкой (timeout). В данном случае, программа по идее должна задержаться на 5 секунд после вывода сообщения: 4. Но по какой-то причине, задержка происходит после сообщения: 3 а сообщения 4 и 5 выводятся одновременно. Почему так?
Re[4]: pthread_mutex_timedlock - ожидание в миллисекундах
От: vdmz  
Дата: 28.10.12 19:57
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, vdmz, Вы писали:


V>>ДимДимыч, угости примером?


ДД>Ну, например, без оптимизационных извращений

ДД>
ДД>  struct timespec ts;
ДД>  long ns;
ДД>…
ДД>  clock_gettime(CLOCK_MONOTONIC, &ts);

ДД>  ns = ts.tv_nsec + ms * 1000 * 1000;
ДД>  ts.tv_nsec = ns % (1000 * 1000 * 1000);
ДД>  ts.tv_sec += ns / (1000 * 1000 * 1000);
ДД>…
ДД>


ДД>При 32-разрядном long позволяет гарантированно задавать таймаут до ≈ 2000 мс.


ДД>Вызов clock_gettime() для случая, если в аттрибутах мютекса также указано использование CLOCK_MONOTONIC. В ином случае clock_gettime() нужно вызывать с соответствующим аргументом.


Есть небольшой класс для проверки мутекса с задержкой. В данном случае, програма должна задержаться на 5 секунд после вывода сообщения: 4. Но по какой-то причине, задержка происходит после сообщения: 3 а сообщения 4 и 5 выводятся одновременно. Почему так?

class CMutex
{
public:
pthread_mutex_t m;
CMutex();
~CMutex();
int fnWaitForMutex(long time);
};
 
CMutex::CMutex()
{
    // Use the mutex attribute to create the mutex
    if (0 != pthread_mutex_init(&m, NULL))
    {
        //lf
    }
}

CMutex::~CMutex()
{
    // Mutex attribute can be destroy after initializing the mutex variable
    if (0 != pthread_mutex_destroy (&m))
    {
        //lf
    }
}

int CMutex::fnWaitForMutex(long time)
{
    struct timeval now;
    struct timespec timeout;

    gettimeofday(&now, NULL);
    uint usec = (time % 1000)*1000 + now.tv_usec;
    timeout.tv_sec = now.tv_sec + time/1000 + usec/1000000;
    timeout.tv_nsec = (usec % 1000000)*1000;

    return pthread_mutex_timedlock(&m, &timeout);
}

int main()
{
    CMutex mutex;
    printf("\n 1");
    mutex.fnWaitForMutex(5000);
    printf("\n 2");
    printf("\n 3");
    printf("\n 4");
    mutex.fnWaitForMutex(5000);
    printf("\n 5");
    return 0;
}
Re[5]: pthread_mutex_timedlock - ожидание в миллисекундах
От: ДимДимыч Украина http://klug.org.ua
Дата: 28.10.12 20:05
Оценка:
Здравствуйте, vdmz, Вы писали:

V>Есть небольшой класс для проверки мутекса с задержкой (timeout). В данном случае, программа по идее должна задержаться на 5 секунд после вывода сообщения: 4. Но по какой-то причине, задержка происходит после сообщения: 3 а сообщения 4 и 5 выводятся одновременно. Почему так?


Прежде всего, стандартный вывод буферизируется построчно. То есть пока в потоке не появится перевод строки, она в терминале может и не появляться. То есть вывод от printf("\n 4") может отработать, но отобразиться в терминале только после того, как следующий вызов переведет строку. Поэтому лучше вместо printf("\n……") вызывать printf("……\n").
Потом, 5000 миллисекунд может переполнить long, если он 32-разрядный. Для таких значений уже нужно пересмотреть арифметику для конкретной архитектуры, чтобы избежать потенциального переполнения.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[5]: pthread_mutex_timedlock - ожидание в миллисекундах
От: ДимДимыч Украина http://klug.org.ua
Дата: 28.10.12 20:07
Оценка:
Здравствуйте, vdmz, Вы писали:

V>Есть небольшой класс для проверки мутекса с задержкой. В данном случае, програма должна задержаться на 5 секунд после вывода сообщения: 4.


Если число секунд целое, зачем тогда миллисекунды?

V>Но по какой-то причине, задержка происходит после сообщения: 3 а сообщения 4 и 5 выводятся одновременно. Почему так?


Из-за буферизации вывода. См. предыдущее сообщение.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[6]: pthread_mutex_timedlock - ожидание в миллисекундах
От: vdmz  
Дата: 28.10.12 20:17
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, vdmz, Вы писали:


V>>Есть небольшой класс для проверки мутекса с задержкой (timeout). В данном случае, программа по идее должна задержаться на 5 секунд после вывода сообщения: 4. Но по какой-то причине, задержка происходит после сообщения: 3 а сообщения 4 и 5 выводятся одновременно. Почему так?


ДД>Прежде всего, стандартный вывод буферизируется построчно. То есть пока в потоке не появится перевод строки, она в терминале может и не появляться. То есть вывод от printf("\n 4") может отработать, но отобразиться в терминале только после того, как следующий вызов переведет строку. Поэтому лучше вместо printf("\n……") вызывать printf("……\n").

ДД>Потом, 5000 миллисекунд может переполнить long, если он 32-разрядный. Для таких значений уже нужно пересмотреть арифметику для конкретной архитектуры, чтобы избежать потенциального переполнения.

Так оно и есть, если поставить \n в конце строки — всё правильно.

По поводу "Потом, 5000 миллисекунд может переполнить long, если он 32-разрядный." — получается если задержка нужна более 2 секунд, время следует указывать в секундах примерно так?:

struct timeval now;
struct timespec timeout;

gettimeofday(&now, NULL);
uint usec = (time % 1000)*1000*1000 + now.tv_usec;
timeout.tv_sec = now.tv_sec + time/1000 + usec/1000000;
timeout.tv_nsec = (usec % 1000000)*1000;
Re[7]: pthread_mutex_timedlock - ожидание в миллисекундах
От: ДимДимыч Украина http://klug.org.ua
Дата: 28.10.12 20:25
Оценка:
Здравствуйте, vdmz, Вы писали:

V>По поводу "Потом, 5000 миллисекунд может переполнить long, если он 32-разрядный." — получается если задержка нужна более 2 секунд, время следует указывать в секундах примерно так?:


V>struct timeval now;

V>struct timespec timeout;

V>gettimeofday(&now, NULL);

V>uint usec = (time % 1000)*1000*1000 + now.tv_usec;
V>timeout.tv_sec = now.tv_sec + time/1000 + usec/1000000;
V>timeout.tv_nsec = (usec % 1000000)*1000;

Вообще смешивать gettimeofday() и pthread_mutex_timedlock() не очень хорошо, т.к. они оперируют с разными структурами представления времени.
Неясно, что такое time в вышеприведенном коде.
В любом случае, без усложнения алгоритма при увеличении времени задержки придется жертвовать точностью, и наоборот, при увеличении точности ограничивается максимально допустимое время.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[8]: pthread_mutex_timedlock - ожидание в миллисекундах
От: vdmz  
Дата: 28.10.12 20:38
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, vdmz, Вы писали:


V>>По поводу "Потом, 5000 миллисекунд может переполнить long, если он 32-разрядный." — получается если задержка нужна более 2 секунд, время следует указывать в секундах примерно так?:


V>>struct timeval now;

V>>struct timespec timeout;

V>>gettimeofday(&now, NULL);

V>>uint usec = (time % 1000)*1000*1000 + now.tv_usec;
V>>timeout.tv_sec = now.tv_sec + time/1000 + usec/1000000;
V>>timeout.tv_nsec = (usec % 1000000)*1000;

ДД>Вообще смешивать gettimeofday() и pthread_mutex_timedlock() не очень хорошо, т.к. они оперируют с разными структурами представления времени.

ДД>Неясно, что такое time в вышеприведенном коде.
ДД>В любом случае, без усложнения алгоритма при увеличении времени задержки придется жертвовать точностью, и наоборот, при увеличении точности ограничивается максимально допустимое время.

Но мутексу нельзя установить атрибут CLOCK_MONOTONIC если только использовать condition variable?
Re[9]: pthread_mutex_timedlock - ожидание в миллисекундах
От: ДимДимыч Украина http://klug.org.ua
Дата: 28.10.12 21:45
Оценка:
Здравствуйте, vdmz, Вы писали:

V>Но мутексу нельзя установить атрибут CLOCK_MONOTONIC если только использовать condition variable?


Да, я подумал об аттрибутах для pthread_cond_init(), поэтому ошибся. Можно ли задать подобные аттрибуты отдельно для мютекса — не знаю, не разбирался. В данном случае это отдельный вопрос. В первую очередь нужно анализировать возможность переполнения при пересчете в наносекунды.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[4]: pthread_mutex_timedlock - ожидание в миллисекундах
От: BulatZiganshin  
Дата: 29.10.12 22:20
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД> long ns;

ДД> ts.tv_nsec = ns % (1000 * 1000 * 1000);

а не проще использовать long long?
Люди, я люблю вас! Будьте бдительны!!!
Re[5]: pthread_mutex_timedlock - ожидание в миллисекундах
От: ДимДимыч Украина http://klug.org.ua
Дата: 29.10.12 23:48
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

ДД>> long ns;

ДД>> ts.tv_nsec = ns % (1000 * 1000 * 1000);

BZ>а не проще использовать long long?


Иногда long long эквивалентно просто long. А там, где не эквивалентно, операции с long long могут быть накладны в плане производительности.
Вообще есть способы более эффективной работы с этими типами данных без ограничения диапазона, но выводить их и приводить здесь просто лень.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[6]: pthread_mutex_timedlock - ожидание в миллисекундах
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.11.12 06:43
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>>> long ns;

ДД>>> ts.tv_nsec = ns % (1000 * 1000 * 1000);
BZ>>а не проще использовать long long?
ДД>Иногда long long эквивалентно просто long. А там, где не эквивалентно, операции с long long могут быть накладны в плане производительности.

Ну с учётом того, что тут и так всякие системные вызовы, или синхронизация в userland, цена на 64 бита вместо 32 копеечная.

ДД>Вообще есть способы более эффективной работы с этими типами данных без ограничения диапазона, но выводить их и приводить здесь просто лень.


The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.