LINUX.ORG.RU

Мьютекс на базе файла

 


0

1

Добрый день. Понадобился мьютекс. Идея была такая: Dir_mutex::lock удаляет каталог mutex_dir(если он пуст), Dir_mutex::unlock создаёт mutex_dir. File_mutex::lock создаёт mutex_dir/file (если каталог существует, File_mutex::unlock удаляет mutex_dir/file. По идее, не должно случиться lock у File_mutex и Dir_mutex. Пожалуйста, не спрашивайте зачем понадобилась такое извращение. Набросал тест:

#include <iostream>
#include <fstream>
#include <thread>
#include <chrono>
#include <stdexcept>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <mutex>
using namespace std;
using namespace std::literals::chrono_literals;
using namespace chrono;


class Dir_mutex
{
public:
    void lock(void)
    {
        while(true)
        {
            if( rmdir("mutex_dir" ) == 0  ||  errno == ENOENT)
                break;
            std::this_thread::sleep_for(50000ns);
        }
    }
    void unlock(void)
    {
        if(mkdir("mutex_dir", S_IRWXU) != 0)
            throw std::logic_error("-------");
    }
};

class File_mutex
{
public:
    void lock(void)
    {
        while(true)
        {
            ofstream file("mutex_dir/file");
            if( file.is_open() )
                break;
            std::this_thread::sleep_for(50000ns);
        }
    }
    void unlock(void)
    {
        if( unlink("mutex_dir/file") != 0 )
            throw std::logic_error("-------");
    }
};

void t1()
{
    Dir_mutex mtx;
    while(true)
    {
        unique_lock<Dir_mutex> lck(mtx); 
        std::this_thread::sleep_for(50000ns);
    }
}

void t2()
{
    File_mutex mtx;
    while(true)
    {
        unique_lock<File_mutex> lck(mtx); 
        std::this_thread::sleep_for(50000ns);
    }
}

int main() 
{
    thread th1(t1);
    thread th2(t2);
    th1.join();
    th2.join();
}

В результате работы, выплёвывается такая ерунда:

...

Message from syslogd@pc at Nov 15 01:15:01 ...
kernel:[  940.604535]  [<c1190172>] ? SyS_open+0x22/0x30

Message from syslogd@pc at Nov 15 01:15:01 ...
kernel:[  940.604535]  [<c14f2f5b>] ? sysenter_do_call+0x12/0x12

Message from syslogd@pc at Nov 15 01:15:01 ...
kernel:[  940.604535] Code: 26 00 8d 7b 54 89 f8 e8 f6 8b 35 00 66 83 4b 02 01 89 f8 c6 00 00 66 66 90 e9 6e ff ff ff 8d 74 26 00 55 89 e5 53 66 66 66 66 90 <8b> 48 1c f6 c2 02 75 0f 5b 5d e9 38 ff ff ff 90 8d b4 26 00 00

Message from syslogd@pc at Nov 15 01:15:01 ...
kernel:[  940.604535] EIP: [<c1199e79>] inode_permission+0x9/0x50 SS:ESP 0068:f750de20
Кто-нибудь может прояснить ситуацию? Это нормальное поведение? Может можно как-то заставить работать данную схему? Ну в целом ясно, что каталог недосоздался, а я его начал использовать. Может можно безопасно проверить наличие каталога?

★★

Под xterm всё намертво зависает, в виртуальной консоли нет.

pavlick ★★
() автор топика
Ответ на: комментарий от i-rinat

Может быть убитая фс или железо или acpi.

anonymous
()
Ответ на: комментарий от dib2

Сложно всё. Вторая половина - lua скрипт, запущенный на проге под вайном. Изматерилая уже весь, хочется послать эту затею нах.. . Простая вроде вещь - сделать мьютекс между двумя программами ...

pavlick ★★
() автор топика

Я может что-то не правильно помню, но именованные семафоры (в том числе бинарные) вроде через файл и работают, не?

CrossFire ★★★★★
()
Последнее исправление: CrossFire (всего исправлений: 2)
Ответ на: комментарий от Elyas

интересная мысль, попробую, отпишусь.

pavlick ★★
() автор топика
Ответ на: комментарий от pavlick

Торговая платформа под линуксом работает? Тогда может лучше какое-нибудь решение поуниверсальнее, типа redis или 0mq?

anatoly
()

Всем спасибо за ответы. Отдельная благодарность Elyas, мьютекс работающий по принципу переименования файла вроде работает.

pavlick ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.