提问人:TheCanadian 提问时间:10/21/2023 更新时间:10/21/2023 访问量:98
如何使用 char 指针写入共享内存?
How do I write to shared memory using a char pointer?
问:
#define MIN_PID 300
#define MAX_PID 5000
#define SPROD_NAME "/sem_prod"
#define SCONS_NAME "/sem_cons"
std::vector<int> pidb = {};
int count = 0;
char* pid_manager::produce(pid_manager& task_manager, char *ptr) {
const char* pid = (std::to_string(task_manager.allocate_pid())).c_str();
std::cout << "Produced: " << pid << std::endl;
std::strcpy(ptr, pid);
ptr += strlen(pid);
count += strlen(pid);
std::cout << ptr <<std::endl;
return ptr;
}
char* pid_manager::consume(pid_manager& task_manager, char *ptr) {
std::cout << "Consumed: " << std::endl;
const char* data = ptr;
std::cout << data << std::endl;
return ptr;
}
void pid_manager::producer(pid_manager& task_manager) {
// connecting to shared semaphores
sem_t *sem_prod = sem_open(SPROD_NAME, 0);
sem_t *sem_cons = sem_open(SCONS_NAME, 0);
// shared memory arguments, and creation/configuration of shared memory using mmap
const int SIZE = 4096;
const char *name = "OS";
int fd;
char *ptr;
fd = shm_open(name,O_CREAT | O_RDWR,0666);
ftruncate(fd, SIZE);
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// creating PID map
task_manager.allocate_map();
// signals to consumer to connect to memory
sem_post(sem_cons);
sem_wait(sem_prod);
ptr = task_manager.produce(task_manager, ptr);
sem_post(sem_cons);
}
void pid_manager::consumer(pid_manager& task_manager) {
// connecting to shared semaphores
sem_t *sem_prod = sem_open(SPROD_NAME, O_CREAT, 0644, 1);
sem_t *sem_cons = sem_open(SCONS_NAME, O_CREAT, 0644, 0);
// shared memory arguments and mapping consumers ptr to shared memory
const int SIZE = 4096;
const char *name = "OS";
int fd;
char *ptr;
fd = shm_open(name, O_RDONLY, 0666);
ptr = (char *)mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
std::cout << ptr << std::endl;
// munmap(ptr,SIZE);
// close(fd);
// return;
// sending signal to producer that consumer is connected to shared memory
sem_post(sem_prod);
// waits for memory to be written, then reads the memory
sem_wait(sem_cons);
std::cout << "Running consume" << std::endl;
ptr = task_manager.consume(task_manager, ptr);
sem_post(sem_prod);
//remove shared memory
shm_unlink(name);
}
int main(){
// initialization of name of process, pid_manager object, and shared memory semaphores
std::string name;
pid_manager task_manager;
sem_t *sem_prod = sem_open(SPROD_NAME, O_CREAT, 0666, 1);
sem_t *sem_cons = sem_open(SCONS_NAME, O_CREAT, 0666, 0);
if (fork() == 0) {
name = "producer";
sem_t *sem_prod = sem_open(SPROD_NAME, 0);
sem_t *sem_cons = sem_open(SCONS_NAME, 0);
}
else {
name = "parent";
if (fork() == 0) {
name = "consumer";
sem_t *sem_prod = sem_open(SPROD_NAME, 0);
sem_t *sem_cons = sem_open(SCONS_NAME, 0);
}
}
// sem_unlink(SPROD_NAME);
// sem_unlink(SCONS_NAME);
// sem_close(sem_prod);
// sem_close(sem_cons);
// return 0;
// runs producer process if not parent
if (name == "producer") {
sem_wait(sem_prod);
std::cout << "Producer Process Executed" << std::endl;
task_manager.producer(std::ref(task_manager));
}
//runs consumer process if not parent
if (name == "consumer") {
sem_wait(sem_cons);
std::cout << "Consumer Process Executed" << std::endl;
task_manager.consumer(std::ref(task_manager));
}
std::cout << "Parent process here!" << std::endl;
wait(NULL);
wait(NULL);
wait(NULL);
sem_close(sem_prod);
sem_close(sem_cons);
return 0;
}
在我的代码中,生产者函数创建共享内存,消费者函数连接到该共享内存,它们通过单个 const char* ptr 访问它。生产者和消费者都调用生产和消费,它们应该进行实际的读取和写入,但两者都冻结在他们写入和读取的行上,没有错误或终止。
所有对 pid 相关内容的调用都只是我们正在构建的项目,它只是一个数组,函数返回它们分配/销毁的数组的索引。 我对共享内存/信号量没有经验,所以我只是通过注释代码并运行它来清除内存,因为我无法让它运行到最后。
我为一大块糟糕的代码道歉,但我真的不知道如何让它工作。
我主要专注于尝试让 produce 函数写入 ptr 指向的内存,因为如果不先运行 produce,consume 甚至无法运行。我老师的例子是:
const char* pid = (std::to_string(task_manager.allocate_pid())).c_str();
sprintf(ptr, "%s", pid);
但我也试过:
const char* pid = (std::to_string(task_manager.allocate_pid())).c_str();
std::strcpy(ptr, pid);
答: 暂无答案
评论
const char* pid = (std::to_string(task_manager.allocate_pid())).c_str();
这将构造一个临时对象,然后获取指向该对象管理的内存块的指针。然后,临时在分号处被销毁,指针变得悬空。随后尝试使用此指针时,会通过在对象生存期结束后访问对象来表现出未定义的行为。std::string