C 共享内存和POSIX信号量
我用C写了一个简单的消费者-制作人程序。当我有一个制作人和一个消费者时,它工作得很好。但当我增加消费者数量时,我的行为很奇怪C 共享内存和POSIX信号量,c,concurrency,posix,ipc,C,Concurrency,Posix,Ipc,我用C写了一个简单的消费者-制作人程序。当我有一个制作人和一个消费者时,它工作得很好。但当我增加消费者数量时,我的行为很奇怪 我开始制作过程 制片人正在制作 我启动消费者流程 消费者在消费,生产者在生产 我启动消费者流程2 使用者进程2从未获得元素 当我开始使用3号、4号消费者时。。。以此类推,同样的情况也会发生 第二个问题: 生产者生产了最多的元素 消费者消费所有元素,但生产者不再继续生产 我不知道为什么会这样 代码: 制作人: #include <semaphore.h> #in
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <fcntl.h>
#include "common.h"
int memoryID;
struct wrapper *memory;
int rc;
void atexit_function() {
rc = shmctl(memoryID, IPC_RMID, NULL);
rc = shmdt(memory);
sem_destroy(&memory->pmutex);
sem_destroy(&memory->cmutex);
sem_destroy(&memory->empty);
sem_destroy(&memory->full);
}
int main(int argc, char **argv) {
atexit(atexit_function);
//creating key for shared memory
srand(time(NULL));
key_t sharedMemoryKey = ftok(".", MEMORY_KEY);
if (sharedMemoryKey == -1) {
perror("ftok():");
exit(1);
}
memoryID = shmget(sharedMemoryKey, sizeof(struct wrapper), IPC_CREAT | 0600);
if (memoryID == -1) {
perror("shmget():");
exit(1);
}
memory = shmat(memoryID, NULL, 0);
if (memory == (void *) -1) {
perror("shmat():");
exit(1);
}
//initialization
printf("Initializtaion !\n");
memset(&memory->array, 0, sizeof(memory->array));
sem_init(&memory->pmutex, 0, 1);
sem_init(&memory->cmutex, 0, 1);
sem_init(&memory->empty, 0, SIZE_OF_ARRAY);
sem_init(&memory->full, 0, 0);
memory->n = -1;
if (memoryID == -1) {
perror("shmget(): ");
exit(1);
}
while(1)
{
int r = rand();
sem_wait(&memory->empty);
sem_wait(&memory->pmutex);
memory->n++;
(memory->array)[memory->n]=r;
printf("Adding task\t Value:%d\tNumber of tasks waiting:%d \n",r,memory->n);
usleep(10000);
sem_post(&memory->pmutex);
sem_post(&memory->full);
}
}
问题解决了。
我正在设置intsem\u init(sem\u t*sem,int pshared,unsigned int value)代码>
我将pshared
值设置为0,但:
我认为你必须把时间留给其他的过程去做sem。在sem发布后,睡你的while 1。不幸的是,这无助于发布的代码看起来不必要的复杂。似乎不需要任何信号量。数据需要一个互斥锁、一个计数器和一个数组。当没有对象/int可供处理时,使用者需要睡眠一段时间。当阵列已满时,生产者需要睡眠一段时间。我还建议,为了避免旧数据得不到及时处理,数组应被视为一个循环列表,带有一个头和尾指针
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
#include <sys/shm.h>
int memoryID;
struct wrapper *memory;
int check_prime(int a);
int main(int argc, char **argv) {
srand(time(NULL));
key_t sharedMemoryKey = ftok(".",MEMORY_KEY);
if(sharedMemoryKey==-1)
{
perror("ftok():");
exit(1);
}
memoryID=shmget(sharedMemoryKey,sizeof(struct wrapper),0);
if(memoryID==-1)
{
perror("shmget(): ");
exit(1);
}
memory = shmat(memoryID,NULL,0);
if(memory== (void*)-1)
{
perror("shmat():");
exit(1);
}
while(1)
{
sem_wait(&memory->full);
sem_wait(&memory->cmutex);
int n = memory->n;
int temp = (memory->array)[n];
printf("Removed item: %d\tPrime:%d\tNumer of tasks left:%d\n",
temp, check_prime(temp),n);
memory->n--;
usleep(10000);
sem_post(&memory->cmutex);
sem_post(&memory->empty);
}
}
#define MEMORY_KEY 12
#define SIZE_OF_ARRAY 10
struct wrapper
{
int array[SIZE_OF_ARRAY];
sem_t empty;
sem_t pmutex;
sem_t cmutex;
sem_t full;
int n;
};
The pshared argument indicates whether this semaphore is to be shared between the
threads of a process, or between processes.
If pshared has the value 0, then the semaphore is shared between the threads of a
process, and should be located at some address that is visible to all threads (e.g., a
global variable, or a variable allocated dynamically on the heap).
If pshared is nonzero, then the semaphore is shared between processes, and should be
located in a region of shared memory (see shm_open(3), mmap(2), and shmget(2)). (Since
a child created by fork(2) inherits its parent's memory mappings, it can also access
the semaphore.) Any process that can access the shared memory region can operate on
the semaphore using sem_post(3), sem_wait(3), etc.