在进程之间使用POSIX信号量(命名信号量,Linux,C)

时间:2017-12-27 17:47:15

标签: c linux posix

这个简单程序的主要思想是通过共享内存在进程之间进行通信,并通过使用信号量限制它们的访问。 '福克斯'创建主要的父流程和3个子流程。孩子是消费者,父母是生产者。孩子应该排队等待父母产生的每一个信息,例如:“PP生成单词'东西' - > P1重生'东西' - > PP生成下一个单词'thing2' - > P2重生'thing2' - > PP生成下一个单词'thing3' - > P3重新'thing3'“ - 只要我愿意,整个东西都在圈内 - 但它不是问题(我使用系统V的信号量工作了)。

我遇到的问题是使用'sem_post'和'sem_wait'导致分段错误(核心转储) - 没有这些程序(当然它没有那么多意义)。我不确定我是否遗漏了那里的东西,也许我应该在子进程中打开那些信号量(但是怎么样?)。我不是那么专家,所以我想问别人帮忙 - 也许只是简单的事情。 :)

如果需要详细说明,我可以写更多相关信息。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>

char tab[50]; //array for information sending through shared memory
char* buffer; //pointer using to actually send something through shared memory

int main()
{
pid_t P1, P2, P3;
sem_t* mutex_prod;   //sem_t* for producer
sem_t* mutex_kons;   //sem_t* for consumer
key_t pd;            //key for shared memory
int pamID;
char STOP = '.';     //character using to stop input in console

//two semaphores are beeing created - first for producer and second for consumers - both are getting 1 as value (since the main idea is to use binary semaphores)
if ((mutex_prod = sem_open("mutex_prod", O_CREAT | O_EXCL, 0666, 1)) == SEM_FAILED)
{
  perror("Semaphore init");
}
if ((mutex_kons = sem_open("mutex_kons", O_CREAT | O_EXCL, 0666, 1)) == SEM_FAILED)
{
  perror("Semaphore init");
}

pd = ftok("home/mrrobot/Pulpit/memsem/p.c", 5); //some key for shared memory

//creation of shared memory
pamID = shmget(pd, sizeof(char), IPC_CREAT | 0666);
buffer = (char*)shmat(pamID, NULL, 0);
*buffer=0;

if(pamID < 0)
  {
    perror("shmget");
    exit(1);
  }

memcpy(buffer, tab, 50);

sem_wait(mutex_prod);   //here's problem starting I suppose and continue with every single next sem_wait or sem_post

switch(P1 = fork())
{
    case -1:
    printf("Blad f. fork");
    exit(1);

    case 0:
    while(1)
    {
        sem_post(mutex_kons);        //post for consumer semaphore
        if((char)*buffer == STOP)
            break;
        printf("PK1 (%d) odczytal dane:\n", getpid());
        printf("%s", buffer);
        sem_wait(mutex_prod);   //wait for producer semaphore
    }
    shmdt(buffer);
    exit(0);

    default:
    switch(P2 = fork())
    {
        case -1:
        printf("Blad f. fork");
        exit(1);

        case 0:
        while(1)
        {
            sem_post(mutex_kons);
            if((char)*buffer == STOP)
                break;
            printf("PK2 (%d) odczytal dane:\n", getpid());
            printf("%s", buffer);
            sem_wait(mutex_prod);
        }
        shmdt(buffer);
        exit(0);
    }

    switch(P3 = fork())
    {
        case -1:
        printf("Blad f. fork");
        exit(1);

        case 0:
        while(1)
        {
            sem_post(mutex_kons);
            if((char)*buffer == STOP)
                break;
            printf("PK3 (%d) odczytal dane:\n", getpid());
            printf("%s", buffer);
            sem_wait(mutex_prod);
        }
        shmdt(buffer);
        exit(0);
    }
}
while(1) //main process - producer
{
    sem_post(mutex_prod); //post semaphore of producer
    printf("PP (%d). Podaj dane:\n", getpid());  
    printf("Aby zakonczyc, wcisnij %c i zatwierdz ENTERem\n", STOP); //printf informing about entering new data or ending program by taping '.'

    scanf("%s", &buffer);    //scanf for new data typed in the terminal 
    if((char)*buffer == STOP)
        break;

    //wait for consumers' semaphore
    sem_wait(mutex_kons);
}
//clearing the memory
shmdt(buffer);
shmctl(pamID, IPC_RMID, 0);
sem_unlink("mutex_prod");
sem_unlink("mutex_kons");
sem_close(mutex_prod);
sem_close(mutex_kons);
wait(NULL);
wait(NULL);
wait(NULL);

return 0;
}

0 个答案:

没有答案