共享内存和 POSIX 信号量
Shared memory and POSIX semaphores
我用 C 编写了简单的消费者-生产者程序。当我有 1 个生产者和 1 个消费者时,它工作正常。但是当我增加消费者数量时,它表现得很奇怪。
- 我启动生产者进程
- 生产者正在生产
- 我启动消费者进程
- 消费者在消费,生产者在生产
- 我启动消费者进程 2
- 消费者进程 2 永远不会获取元素
- 当我启动 3 号、4 号等消费者时,同样的情况发生了
第二题:
- 生产者生产了最大的元素
- 消费者消费所有元素,但生产者不再继续生产
我不知道为什么会这样。
代码:
制作人:
#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);
}
}
消费者:
#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);
}
}
common.h:
#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;
};
问题已解决。
我正在设置 int sem_init(sem_t *sem, int pshared, unsigned int value);
我将 pshared
值设置为 0 但是:
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.
我用 C 编写了简单的消费者-生产者程序。当我有 1 个生产者和 1 个消费者时,它工作正常。但是当我增加消费者数量时,它表现得很奇怪。
- 我启动生产者进程
- 生产者正在生产
- 我启动消费者进程
- 消费者在消费,生产者在生产
- 我启动消费者进程 2
- 消费者进程 2 永远不会获取元素
- 当我启动 3 号、4 号等消费者时,同样的情况发生了
第二题:
- 生产者生产了最大的元素
- 消费者消费所有元素,但生产者不再继续生产
我不知道为什么会这样。
代码:
制作人:
#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);
}
}
消费者:
#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);
}
}
common.h:
#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;
};
问题已解决。
我正在设置 int sem_init(sem_t *sem, int pshared, unsigned int value);
我将 pshared
值设置为 0 但是:
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.