Совместное использование переменной между C и Python

Я использую именованный канал FIFO для связи между C (числа, генерирующие цикл - C) и python (прослушивание числа, сгенерированного C, и чтение их, и их обработка). Код работает хорошо, за исключением каждого сгенерированного числа в C. Мне нужно закрыть fifo, чтобы увидеть его в Python, иначе он не будет отображаться в Python, пока не будет вызвана команда закрытия. Я не знаю, является ли открытие и закрытие FIFO хорошей идеей для правильного чтения в коде Python или нет. Я должен отметить, что код C генерирует число каждые 50 миллисекунд. Вот почему я сомневаюсь, что открытие и закрытие - хорошая идея или нет. Вот мои коды на C и Python:

C как сервер:

while (1){
            t=time_in_ms();
            if (t-t0>=50){
                    t0=t;
                    flag=1;
            }
            else{
                    flag=0;
            }
            if (flag==1){
                    flag=0;
                    printf("%lld %lld\n",count,t);
                    count+=1;
                    fprintf(f,"%lld\r",t);
                    fflush(f);
                    fclose(f);
                    f=fopen("fifo","w");

            }
    }

И код на Python в качестве клиента:

with open(FIFO) as fifo:
print("FIFO opened")
while True:
    data = fifo.read()
    if len(data) == 0:
            count=count+1
    else:
            count=0
    if count>2000:
        print("Writer closed")
        break
    print data
    x=x+1

person user2684657    schedule 12.11.2017    source источник
comment
Возможный дубликат интеграции Python и C ++   -  person wwii    schedule 12.11.2017
comment
Проблема в том, что на обоих концах fifo вы используете буферизованный ввод-вывод. Вы должны использовать open/write на стороне C и os.open/os.read на стороне python!   -  person Antti Haapala    schedule 12.11.2017
comment
Могу ли я узнать, что вы имеете в виду под использованием open / write на стороне C и os.open/os.read на стороне python? Не могли бы вы сообщить мне, как мне изменить код, чтобы учесть ваши комментарии?   -  person user2684657    schedule 12.11.2017
comment
Что касается C-кода: man 2 open man 2 write Также обратите внимание на: man 3 fflush При работе с C страницы руководства в Linux являются прекрасным и отличным ресурсом.   -  person David Bern    schedule 12.11.2017
comment
Я думаю, что говорит @AnttiHaapala; не относитесь к FIFO как к ПОТОКУ, вместо этого используйте дескриптор файла. Подобно функции write или dprintf. Я должен добавить, что я никогда раньше не использовал dprintf и просто размышлял о поведении   -  person David Bern    schedule 12.11.2017
comment
Обратите внимание, что в Python буферизованный file.read будет пытаться читать до EOF. Одним из вариантов было бы использование readline, но это не значит, что это было бы полностью без проблем.   -  person Antti Haapala    schedule 12.11.2017


Ответы (1)


Вот небольшой рабочий пример

Сторона Python:

with open('./test_out.fifo', 'r') as fo:
    message = fo.readline()
    print(message)

На "серверной" стороне C

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fifo_fd;
    fifo_fd = open("./test_out.fifo", O_WRONLY);
    dprintf(fifo_fd, "testing123\n");

    while(1)
    {
        sleep(1);
    }
    return 0;
}

Бесконечный цикл в конце C-программы просто демонстрирует, что нам не нужно закрывать файл до того, как данные станут доступны для чтения в программе python.

Я также должен сказать, что я давно не занимался C-кодом.

person David Bern    schedule 12.11.2017
comment
Знаете ли вы, есть ли способ, которым на стороне Python я могу проверить FIFO, если данные готовы, поймать его, иначе я смогу делать другие мысли? Кажется, сейчас я нахожусь в режиме часов, который будет ждать новых данных. Я спрашиваю, потому что мне нужно обработать данные после их получения на python, я не хочу терять мощность процесса системы, которая блокируется при чтении FIFO. - person user2684657; 13.11.2017
comment
позвольте мне подумать об этом на мгновение. Я вернусь к вам здесь. - person David Bern; 13.11.2017
comment
позвольте мне объяснить мой случай, мой датчик в C получает данные каждые 50 миллисекунд и помещает в FIFO, на стороне Python, когда в FIFO есть данные, я читаю их и анализирую после завершения анализа, я должен вернуться и проверить, есть ли какие-либо новые данные в FIFO, прочтите их и сделайте это снова. Меня беспокоит только то, что если анализ данных занимает более 50 мсек, я не потеряю данные из FIFO. И я не знаю, какова длина фифо. - person user2684657; 13.11.2017
comment
Чтобы ответить на размер. Попробуйте эту команду sysctl fs.pipe-max-size Что касается другой проблемы, я уверен, что есть решения. Задумайтесь над проблемой. Сформулируйте вопрос, и я постараюсь помочь вам его решить. Почему я не помогу вам здесь в комментариях? Просто, возможно, у кого-то такая же проблема, он / она не найдет здесь ответа, и если вы немного подумаете о проблеме, возможно, вы найдете кого-то, у кого уже был этот точный вопрос. Не стесняйтесь давать URL-адрес вашего будущего вопроса в этом комментарии - person David Bern; 13.11.2017
comment
Конечно, я подумаю и дам вам знать о своих выводах. - person user2684657; 13.11.2017
comment
Здесь нужно подумать об одном. Если вы производите данные с большей скоростью, чем вы способны их обрабатывать, как долго вы сможете это делать, прежде чем у вас закончится ОЗУ? Ставка только периодическая, и потребитель сможет наверстать упущенное? В этом случае просто увеличьте разрешенный размер FIFO с помощью команды, которую я вам дал. Если вас беспокоит то, что вы не хотите тратить время на ожидание поступления данных на FIFO или, возможно, на их комбинацию. Найдите блокирующее / неблокирующее чтение FIFO. Это начинает все больше походить на вопрос о технологиях, а не о проблемах программирования. - person David Bern; 13.11.2017
comment
точно второй случай, я имею в виду, что в зависимости от данных, которые мы получаем в Python, обработка может занять больше времени, но я могу сказать, что это происходит только в 10% данных, для 90% анализ данных завершится до того, как новые данные поступят в буфер . Тогда я думаю, что если размер буфера достаточно велик, со мной все будет в порядке. ' - person user2684657; 13.11.2017
comment
В этом случае просто увеличьте размер буфера FIFO с помощью команды sysctl, которую я дал вам в предыдущем комментарии, и время, в течение которого вам придется ждать появления полной строки в FIFO, не должно быть проблемой. - person David Bern; 14.11.2017