Linux信号量

时间:2017-01-20 10:48:21

标签: c linux semaphore mkfifo

我正在寻找Linux中同步问题的帮助。我是新手,我想我真的不懂如何使用信号量进行同步。我的任务是同步两个访问文件的进程 - 一个从另一个进程读取fifo,写入该文件,然后另一个读取。我知道我的代码缺乏同步,但我不知道如何做到这一点。

代码:

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);
         }
    }

1 个答案:

答案 0 :(得分:2)

您的主要问题似乎与信号量如何工作的概念有关。信号量最好被视为生产者和消费者之间的信号。当制作人做了一些事情时,他们会在信号量上发布信号,消费者会等待信号量,直到制作人发出信号。

因此,在您的情况下,消费者和生产者之间应该只有一个信号量 - 他们应该共享此信号量以进行同步。此外,信号量应从零开始,因为尚未生成任何内容。每次生产者发布到信号量时,值将增加1,当消费者等待信号量时,消费者将在值为零时休眠,直到生产者帖子和值增加并变为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);
}