我有以下程序:
#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((。