c-如何从共享内存打印存储的数据



我有以下程序:

#include <stdio.h>
#include <sys/types.h>
#define MAX_COUNT 100
void ChildProcess(void);
void ParentProcess(void);
void main(void)
{
pid_t pid;
pid = fork();

if (pid == 0)
ChildProcess();
else
ParentProcess();
}
void ChildProcess(void)
{
int i;
for (i = 1; i <= MAX_COUNT; i++)
printf(" This line is from child, value = %dn", i);
printf(" *** Child process is done ***n");
}
void ParentProcess(void)
{
int i;
for (i = 1; i <= MAX_COUNT; i++)
printf("This line is from parent, value = %dn", i);
printf("*** Parent is done ***n");
}

我必须修改它,使父级和子级都以以下方式从共享内存打印存储的数据:

  • 在父级中创建并初始化共享内存
  • 用5个整数填充共享内存。(我应该分配足够的共享内存来存储这5个int。(
  • 从父级分叉到子级
  • 如果fork成功,则子进程必须打印共享存储器中存储的值,如预期输出所示,其中N1、N2、N3、N4、N5是在共享存储器中找到的数字

预期输出

我在ParentProcess函数中做了以下操作:

void ParentProcess(void)
{
int i;

for (i = 1; i <= MAX_COUNT; i++)
printf("This line is from parent, value = %dn", i);
printf("*** Parent is done ***n");

int localVar = 0;
int* p = (int*) malloc(2);
pid_t childPID = fork();
*p = 0;

if (childPID >= 0)
{
printf("nChild process has startedn");
if (childPID == 0)
{
localVar++;
globalVar++;
printf("Child process has found the following data %d,", *p);
*p = 70;
printf( " %d,", *p); 
*p = 66; 
printf(" %d,", *p); 
*p = 51; 
printf(" %d,", *p); 
*p = 90; 
printf(" %d in shared memoryn",*p); 

printf("Child is existingnn");
} 
} 

}

现在我意识到我完全错了,但我不知道如何解决这个问题。我想我必须使用shmget来创建共享内存,但接下来呢?如何在其中存储值?

如果你发现你不能帮我做这件事,或者它太长了,请分享我可以了解更多关于Linux中C编程的来源,特别是关于共享内存的使用。提前感谢

最好先弄清楚你想做什么,因为就我阅读你的代码而言,你在代码中调用了两次fork(((一次在main((函数中,一次在ParentProcess((函数(

因此,我为父/子共享内存编写了通用解决方案。有几种方法可以实现共享内存,但这是这里代码的修改版本如何在C 中使用Linux共享内存

#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/wait.h>
void *create_shared_memory(size_t size)
{
int protection = PROT_READ | PROT_WRITE;
int visibility = MAP_SHARED | MAP_ANONYMOUS;
return mmap(NULL, size, protection, visibility, -1, 0);
}
int main()
{
// Allocate 4 ints
void *shmem = create_shared_memory(sizeof(int)*4);
if( shmem == NULL ){
fprintf(stderr, "Failed to create shared memoryn");
return -1;
}
// Initialize 4 ints
((int*)shmem)[0] = 10;
((int*)shmem)[1] = 100;
((int*)shmem)[2] = 1000;
((int*)shmem)[3] = 10000;
int pid = fork();
if (pid == 0)
{
// Print 4 ints in child
printf("Child reading int 0: %dn", ((int*)shmem)[0]);
printf("Child reading int 1: %dn", ((int*)shmem)[1]);
printf("Child reading int 2: %dn", ((int*)shmem)[2]);
printf("Child reading int 3: %dn", ((int*)shmem)[3]);
printf("Child endn");
}
else
{
printf("Parent waiting for child ends...n");
waitpid(pid, NULL, 0);
printf("Parent endsn");
}
int ret = munmap(shmem, sizeof(int)*4);
if( ret != 0 ){
fprintf(stderr, "Failed to unmap shared memoryn");
return -1;
}
return 0;
}

我写了一小段c代码,您可能会觉得它很有用:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#define NUM_INTS    5
int main(int argc, char *argv[])
{
key_t key = (key_t) 123456;
int shmgetrc, semgetrc;
struct shmid_ds ds;
int *shared_values;
int i;
struct sembuf sops[2];
int semid;
sops[0].sem_num = 0;        /* Operate on semaphore 0 */
sops[0].sem_op = 0;         /* Wait for value to equal 0 */
sops[0].sem_flg = 0;
sops[1].sem_num = 0;        /* Operate on semaphore 0 */
sops[1].sem_op = 1;         /* Increment value by one */
sops[1].sem_flg = 0;

/* create SHM segment */
shmgetrc = shmget(key, NUM_INTS * sizeof(int), IPC_CREAT | IPC_EXCL | 0x180);
if (shmgetrc < 0) {
perror("shmget failed...");
exit(1);
}
/* retrieve the address of the segment */
shared_values = (int *) shmat(shmgetrc, NULL, 0);
/* create a semaphore */
semgetrc = semget(key, 1, IPC_CREAT | IPC_EXCL | 0x180);
if (semgetrc < 0) {
perror("semget failed...");
exit(1);
}
/* lock the semaphore */
if (semop(semgetrc, sops, 2) == -1) {
perror("semop lock failed ...");
exit(1);
}
/* fill it with values */
for (i = 0; i < NUM_INTS; ++i) {
shared_values[i] = i;
}
/* unlock the semaphore */
sops[0].sem_op = -1;
if (semop(semgetrc, sops, 1) == -1) {
perror("semop release failed ...");
exit(1);
}
/* here something else could happen */
sleep(60);
/* lock the semaphore */
sops[0].sem_op = 0;
if (semop(semgetrc, sops, 2) == -1) {
perror("semop lock failed ...");
exit(1);
}
/* print values */
for (i = 0; i < NUM_INTS; ++i) {
printf("%d ", shared_values[i]);
}
printf("n");
/* unlock the semaphore */
sops[0].sem_op = -1;
if (semop(semgetrc, sops, 1) == -1) {
perror("semop release failed ...");
exit(1);
}
/* remove the semaphore */
if (semctl(semgetrc, semgetrc, IPC_RMID) < 0) {
perror("semctl failed ...");
exit(1);
}
/* remove shm segment again */
if (shmctl(shmgetrc, IPC_RMID, &ds) < 0) {
perror("shmctl failed ...");
exit(1);
}
exit(0);
}

我无意写有史以来最漂亮的代码,只是举个例子:

  • 如何创建shm段
  • 如何检索和使用地址
  • 如何删除

此外,我还使用了一个信号量来保护访问。

与另一个答案相反,我使用了ipc接口,而不是mmap((。

最新更新