这个简单程序的主要思想是通过共享内存在进程之间进行通信,并通过使用信号量限制它们的访问。 '福克斯'创建主要的父流程和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;
}