从共享内存段复制数据会导致客户端出现段错误(信号量和共享内存)

标签 c synchronization shared-memory semaphore memcpy

我正在尝试编写一个简单的生产者和消费者程序(两个不相关的进程)。 ,具有共享内存和信号量。我使用信号量empty和full作为条件变量,并将数据从生产者memcpy到共享内存段中。而且,我尝试将数据 memcpy 到使用者的本地变量中,但这导致了段错误。这很奇怪,我不明白发生了什么。这是代码。

生产者和消费者的共同部分(信号量和共享内存创建):

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>
#include<stdlib.h>
#include <sys/shm.h>

struct a
{
int a;
int b;
}a_s;
void wait(int semid)
{
int err,nsops=1;
struct sembuf *sops = (struct sembuf *) malloc(sizeof(struct sembuf));
sops[0].sem_num = 0;
sops[0].sem_op = -1;
sops[0].sem_flg = 0;
err=semop(semid, sops, nsops);
if(err < 0)
    printf(" unable to do the sop \n");
}

void signal(int semid)
{
int err,nsops=1;
struct sembuf *sops = (struct sembuf *) malloc(sizeof(struct sembuf));      
sops[0].sem_num = 0;
sops[0].sem_op = 1;
sops[0].sem_flg = 0;
err=semop(semid, sops, nsops);
if(err < 0)
    printf(" unable to do the sop \n");
}


int main()
{
int i, err;
int full,empty;
key_t full_key = 1234, empty_key = 5678;
int sem_flg = IPC_CREAT | 0666;
int nsems = 1;
int nsops = 2;
    int shmid;
void *string;
void *s;
int shm_key = 9999;

struct a *a_str;
/*****************************************/

empty = semget(empty_key, nsems, sem_flg);
if(empty < 0)
    printf(" failed to initialize the semaphore \n");

semctl(empty, 0, SETVAL, 1) ;
/****************************************/
full = semget(full_key, nsems, sem_flg);
if(full < 0)
    printf(" failed to initialize the semaphore \n");

semctl(full, 0, SETVAL, 0) ;    

/*****************************************/
shmid = shmget(shm_key, 30, IPC_CREAT|0666); 
if(shmid < 0) 
    printf(" unable to create shmem \n");
else
    printf(" created shm \n");

string = shmat( shmid, NULL, 0); 
if( string == (void * ) (-1))
    printf(" unable to attach the string \n");
else
    printf(" success with shmat \n");
s = string;
/******************************************/

生产者:输入数据

while(1)
{
    wait(empty);
    sleep(1);
    memcpy( string, (void *) a_str, sizeof(struct a));
    printf(" wrote the string \n");
    signal(full);
}

消费者:复制数据并显示

while(1)
{

wait(full);
printf(" after full \n");
memcpy((void *)a_str, (void *)s, sizeof(struct a));
printf(" copied the memory from string \n");
printf(" a %d b %d \n",((struct a *)a_str)->a, ((struct a *)a_str)->b);
sleep(1);
memcpy(s, string, 7);


signal(empty);
}

return 0;
}

有人可以告诉我为什么它的段错误吗?我只是从内存段复制地址。可能会出现什么问题?

最佳答案

Could anybody please let me know why its seg faulting??

您没有初始化a_str,这可以通过以下方式修复

a_str = malloc(sizeof(*a_str));

典型的使用未初始化指针,又名野指针问题。

<小时/>

顺便说一句,POSIX IPC API 比 System V IPC API 更好。参见

  • mq_overview (7) - POSIX 消息队列概述
  • sem_overview (7) - POSIX 信号量概述
  • shm_overview (7) - POSIX 共享内存概述

关于从共享内存段复制数据会导致客户端出现段错误(信号量和共享内存),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22521773/

相关文章:

c - 将列表添加到 C 中已有的列表中

在共享内存 c 中创建 char 的二维数组

c++ - 是否可以与另一个进程共享现有的 RAM block ?

c - C中指针的内存分配

用于定义带有回调的测试方法的 C 宏

c - 需要一个 union 来从 20 个字符生成 5 个整数

ios - 在迭代之前复制集合是否足以防止同步问题?

java - 如何在java应用程序中将本地数据库与服务器同步

java - Java 中的死锁 : When they occur?

delphi - 在 PC 之间共享 Delphi 中的公共(public)内存区域