LINUX.ORG.RU

Коммуникация процессов через файл

 ,


0

1

Здравствуйте.
Имеем две программы и разделяемый файл, механизм синхронизации из виду упущу. Первая exe пишет файл, после каждой записи делает flush(), вторая читает. Можно ли быть уверенным, что читаются актуальные данные, а не какой-нибудь буферезированный хлам? Ведь можно буферезировать как out так и in, но ifstream flush() не имеет.

Экспериментальным путём проблем не обнаружил. Даже ofstream ведёт себя так, как будто буфера не имеет (назначал буфер руками). 2.cpp моментально видит свежие данные:

//1.cpp
int main()
{
    std::ofstream f("fff"); 
    char buf[100];
    f.rdbuf()->pubsetbuf(buf, 90);
    while(true)
    {
        f.seekp(0);
        int i;
        cin >> i;
        f << i;
        //f.flush();
    }
}
//2.cpp
int main()
{
    std::fstream f("fff"); 
    char buf[100];
    f.rdbuf()->pubsetbuf(buf, 90);
    f << 4 << 3;
    while(true)
    {
        this_thread::sleep_for(1s);
        f.seekg(0);
        int i;
        f >> i;
        cout << i << endl;
    }
}
Опираясь на плюсовые стд потоки, можно ли считать схему рабочей, при которой одна экзе пишет (и делает флаш), а другая читает? Т.е. будет ли вторая получать свежие данные при любых условиях (любая ос и т.д.)?

★★

Последнее исправление: beastie (всего исправлений: 1)

А вот это зачем:

f.rdbuf()->pubsetbuf(buf, 90);
Чтобы всех запутать?

ЗЫ кстати, я могу сразу сказать, что на оффтопике сабж просто не будет работать в виду блокировки файла пишущим процессом (даже если исправить ошибки в коде).

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

А какие ошибки в коде? Отсутствие #include и using namespace?

#include <chrono>
#include <iostream>
#include <thread>
#include <fstream>
using namespace std;
using namespace chrono;
using namespace std::literals::chrono_literals;
C этим скомпилируется, думаю.

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

можно ли считать схему рабочей

Конечно нет ибо до flush кеш может быть записан но частично и в это время прочитан твоей второй программой. man flock

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

Я ведь отметил, что вопросы синхронизации здесь не поднимаю, конечно она будет.
Для меня вопрос в следующем: нужно ли читающему процессу создавать ifstream перед каждым чтением? Или можно открыть один раз и не дёргаться? На записывающей стороне есть flush(), а с читающей стороной не совсем ясно.

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

Без понятия. Этой фигней не пользуюсь и никому не советую. Ты думаешь что если пишешь на c++ то должен эту фигню юзать? Это не так. man open, man close, man write, man read, man stat, man flock, man fsync

anonymous
()

А почему не использовать нормальные способы синхронизации процессов? В конце концов, то, что ты хочешь сделать здесь можно реализовать через pipe.

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

+1, есть же mkfifo (см. man 3 mkfifo). И не надо извращаться с блокировками и синхронизацией.

Kiborg ★★★
()

Можно (хотя нет никаких гарантий ибо это не поведение по стандарту), но ЕМНИП только в реализации flush от microsoft, ибо там сбрасывается буфер. Во всех других компиляторах тебя ждет куча сюрпризов. И да, не пиши код на C++, не разобравшись с потоками, очень прошу.

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

С тех пор, как .exe - расширение исполняемых файлов Windows. ELF-файлы, являющиеся де-факто стандартом исполняемых файлов Unix, обычно не имеют расширения.

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

Беги оттуда. Если тот, с кем ты работаешь, реально считает, что общение процессов через файлики на HDD - норма, то нафиг такие коллеги нужны. Или у вас там Дедал со своим «червером(!) распределенных вычеслений»™ обосновался?

cherry-pick
()

хуярь лучше через принтер-сканер, на бумаге оно всегда надёжнее

anonymous
()

Зачем файл?
man fifo #именованный канал
man pstreams #напрямую между процессами через stdin/out
Еще на венде можно через сетевые сокеты локалхоста обеспечить общение

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 2)

Мои 5 евроцентов: а я использовал даже stderr для управления между программами, ну надо было извратиться. А еще заметил что когда работаешь с fdsink (stderr) из gstreamer то там ввод попадает цельными пакетами, будто буферизуется и не надо выпарсивать блоки данных, т.к. если что-то пришло то оно уже нужной длины - видимо там делается flush...

Уверенности ТС-у не добавлю, но схема кажется рабочей, раз в частном случае используется даже таким не-студенческим ПО типа gstreamer...

P.S. Предлагаю stderr вместо файла, нафига физические файлы? И мне кажется это будет работать как минимум на win/lin/mac...

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.