2017-01-20 3 views
-3

Я ищу помощь по синхронизации в Linux. Я новичок, и я думаю, что я действительно не понимаю, как использовать семафоры для синхронизации. Моя задача - синхронизировать два процесса, которые обращаются к файлу - один читает из fifo из другого процесса, записывает в этот файл, затем читает другой. Я знаю, что в моем коде не хватает синхронизации, но я не знаю, как это сделать.Семафоры Linux

Код:

sem_t writer, reader; 
    void readFromFifoSendToFile(void) { 
     sem_init(&writer, 1, 1); 
     FILE *fp; 
     char buffer[100]; 
     FILE *file; 
     file = fopen("file", "w+"); 
     fclose(file); 

     while(1) { 
        sem_wait(&writer); 
        fp = fopen("fifo", "r"); 
        fscanf(fp, "%s", buffer); 
        fclose(fp); 
        file = fopen("file", "a+"); 
        fputs(buffer, file); 
        fclose(file); 
        sem_post(&writer); 
     } 
    } 

    void readFromFileAndPrint(void) { 
     sem_init(&reader, 1, 1); 
     FILE *fp; 
     char buffer[100]; 
     int counter = 0; 

     while(1) { 
        sem_wait(&reader); 
        counter++; 
        if(counter == 1) { 
         sem_wait(&writer); 
        sem_post(&reader); 
        fp = fopen("file", "r"); 
        fscanf(fp, "%s", buffer); 
        fclose(fp); 
        printf("%s", buffer); 
        sem_wait(&reader); 
        if(counter == 0) { 
         sem_post(&writer); 
        } 
        sem_post(&reader); 
     } 
    } 
+0

Вам нужно использовать семафоры или использовать [named pipess] (http://www.linuxjournal.com/article/2156)? – Soren

+1

Это школьное задание? Вы пропустили лекцию о синхронизации? В вашей курсовой литературе ничего нет? Вы пробовали его искать (есть тысячи примеров и руководств по всей сети)? –

+0

@Soren Мне не нужно использовать семафоры, но мне нужно использовать файл. Я пробовал искать ответ, но я не понимаю этих концепций. Я парень Java, не использовал эти черты Linux. Да, это школьное задание. – voidmat

ответ

1

Ваша главная проблема, как представляется, связано с понятием о том, как семафор работ. Семафоры лучше всего рассматривать как сигнал между производителем и потребителем. Когда производитель сделал что-то, они отправляют сигнал на семафор, и потребитель будет ждать на семафоре, пока производитель не опубликует сигнал.

Так что в вашем случае должен быть только один семафор между потребителем и производителем - они должны делиться этим семафором для их синхронизации. Кроме того, семафор должен начинаться с нуля, так как ничего еще не было создано. Каждый раз, когда сообщение производителя в семафор значение будет увеличиваться на единицу, потребитель, когда он ждет на семафоре, будет спать, если значение равно нулю, до тех пор, пока сообщение производителя и значение не увеличится и не станет единым. Если производитель намного быстрее, чем потребитель, стоимость семафора может повыситься и быть более чем одним, что является прекрасным, если потребитель потребляет продукцию в том же размере, что и производитель.

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

#include <semaphore.h> 
#include <pthread.h> 
#include <stdio.h> 
#include <unistd.h> 

sem_t thereBeData; 

void* readFromFifoSendToFile(void*) { 

    FILE *fp = stdin; 
    char buffer[100]; 
    FILE *file; 

    file = fopen("file", "a+"); 

    while(1) { 
     fscanf(fp, "%s", buffer); 

     fprintf(file,"%s\n",buffer); 
     fflush(file); 

     sem_post(&thereBeData); // signal the consumer 
    } 
} 

void* readFromFileAndPrint(void*) { 
    FILE *fp = 0; 
    char buffer[100]; 
    int counter = 0; 

    while(1) { 
     sem_wait(&thereBeData); // Waiting for the producer 

     if (!fp) fp = fopen("file", "r"); 
     fscanf(fp, "%s", buffer); 

     printf("%s\n", buffer); 
    }  
} 


int main(void) 
{ 
    pthread_attr_t attr; 
    pthread_t thread1; 
    pthread_t thread2; 

    sem_init(&thereBeData, 0,0); 
    pthread_attr_init(&attr);  
    pthread_create(&thread1, &attr, readFromFifoSendToFile, (void*)0); 
    pthread_create(&thread2, &attr, readFromFileAndPrint, (void*)0); 

    sleep(10); 
} 
+0

спасибо, очень полезно сообщение :) – voidmat

Смежные вопросы