C: Fifo между потоками, написанием и чтением строк - PullRequest
2 голосов
/ 08 июня 2010

Здравствуйте еще раз дорогой интернет,

Я пишу небольшую программу, которая, помимо прочего, записывает в файл журнала все полученные команды.
Для этого я хочу использовать поток, который будет пытаться читать только из канала, тогда как основной поток будет писать в этот канал всякий раз, когда это необходимо.

Поскольку я не знаю длины каждой строковой команды, я подумал о написании и чтении указателя на char buf[MAX_MESSAGE_LEN].
Поскольку то, что я пробовал до сих пор, не работает, я опубликую все возможное: P

   char str[] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n";  
    if (pipe(pipe_fd) != 0) 
        return -1;  
    pthread_t log_thread;  
    pthread_create(&log_thread,NULL, log_thread_start, argv[2]);  
    success_write = 0;  
    do {  
        write(pipe_fd[1],(void*)&str,sizeof(char*));  
    } while (success_write < sizeof(char*));

и поток делает это:

    char buffer[MAX_MSGLEN];  
    int success_read;  
    success_read = 0;  
    //while(1) {  
        do {  
            success_read += read(pipe_fd[0],(void*)&buffer, sizeof(char*));  
        } while (success_read < sizeof(char*));  
    //}  
    printf("%s",buffer); 

(Извините, если это не отступ, я не могу понять этот редактор ...) о, и pipe_fd[2] является глобальным параметром.

Итак, любая помощь с этим, как я думал, или как я мог читать строки, не зная длины, была бы очень признательна.

Кроме того, я работаю над Eclipse IDE C / C ++ версии 1.2.1 и не могу настроить компилятор, чтобы он связывал библиотеку pthread с моим проектом. Я прибег к написанию собственного Makefile, чтобы он работал (каламбур: P). Кто-нибудь знает, как исправить проблему со ссылкой? Я посмотрел в Интернете, но все, что я нашел, это решения, которые, вероятно, хороши в более старой версии, потому что вкладки и клавиши выбора разные.

В любом случае, спасибо, куча интернета! Йонатан

Ответы [ 6 ]

0 голосов
/ 08 июня 2010

Итак, любая помощь с этим, как я думал, или как я мог читать строки, не зная длины, была бы очень признательна.простой протокол для связи через FIFO / канал.Поток записи записывает один байт в FIFO, чтобы указать длину сообщения, а затем записывает сообщение переменной длины.Читатель прочитает один байт, чтобы узнать длину сообщения, а затем выполнит следующую команду чтения для указанной длины сообщения.

Вы можете проверить этот ответ к аналогичному вопросу о FIFO для более подробной информации.

0 голосов
/ 08 июня 2010

Вы не обновляете success_write в цикле.

0 голосов
/ 08 июня 2010

Вы пробовали пару сокетов (AF_UNIX, SOCK_DGRAM)? Он надежен по своей природе, а также разграничивает сообщения для вас.

В вашем случае вы должны убедиться, что MAX_MESSAGE_LEN меньше, чем PIPE_BUF, предел платформы для внутреннего буфера pipe ().

И, очевидно, измените отправку / получение указателя на отправку фактической строки, например ::

-   char str[] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n";
+   char str[MAX_MESSAGE_LEN] = "hello log thread 123456789 10 11 12 13 14 15 16 17 18 19\n";

- write(pipe_fd[1],(void*)&str,sizeof(char*));
+ write(pipe_fd[1],(void*)&str,MAX_MESSAGE_LEN);
0 голосов
/ 08 июня 2010

Вам действительно нужна дополнительная нить для этого? Как вы обнаружите, добавление потоков значительно увеличивает сложность ... в этом случае запись в канал вряд ли будет намного быстрее, чем запись в файл - и на самом деле на практике это может оказаться медленнее, поскольку write() не имеет буферизации, которой обладают fprintf() и друзья. Лучшее решение может быть просто написать в лог-файл напрямую ...

0 голосов
/ 08 июня 2010

Мне кажется, что если вы просто слишком много читали или писали, то ваш код заканчивался бы. Вы должны иметь, в то время как success_read

0 голосов
/ 08 июня 2010

Почему вы читаете и записываете данные кусками sizeof(char*) байтов, что составляет 4 или 8 байтов? Вы не обязаны читать и записывать одинаковое количество байтов!

Если ваша проблема в том, что вы не получаете данные в потоке чтения, вам следует подумать о синхронизации после записи, используя sync().

...