当前位置:  技术问答>linux和unix

帮忙看看这个Linux共享内存程序什么地方有问题?

    来源: 互联网  发布时间:2017-01-02

    本文导语:  问题是这个样子的,我利用共享内存在两个进程之间传递数据,一个是消费者,另一个是 生产者。他们的代码很类似。 消费者代码: #include  #include  #include  #include  #include  #include  #include  #include  #include  #include...

问题是这个样子的,我利用共享内存在两个进程之间传递数据,一个是消费者,另一个是
生产者。他们的代码很类似。
消费者代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using std::string;


union semun
 {
    int val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
};

string buf;//存储记录

//与共享内存有关的变量
int shmid=-1;// 共享内存的id
void * shm_re=(void *)0;
string * shm_records;// 保存共享内存的起始位置
int full=-1;
int empty=-1;
//函数接口说明
void daemon_start_task();//初始化函数

//封装的信号量处理接口
int set_semvalue(int sem_v,int semid);
void del_semvalue(int semid);
int sem_post(int semid);//加操作
int sem_wait(int semid);//减操作


int main(int argc,char * arg[])
{
  daemon_start_task();
  //设置两个信号量的初始值
  set_semvalue(0,full);
  set_semvalue(1,empty);


  for(;;)
  {
    sem_wait(full);
    printf("%sn",(*shm_records).c_str());
    sem_post(empty);
    sleep(2);

  }
return 0;

}



void daemon_start_task()
{
    shmid=shmget((key_t)0x12356,sizeof(string),0666|IPC_CREAT);
    printf("shmid=%dn",shmid);
    shm_re=shmat(shmid,NULL,0);
   shm_records=(string *)shm_re;//此时可以使用共享内存
    printf("共享内存段在 %Xn",(int)shm_re);

    full=semget((key_t)0x8978,1,0666|IPC_CREAT);//只需要由消费者初始化一次即可
    empty=semget((key_t)0x74566,1,0666|IPC_CREAT);


}

//1成功,0失败
/*函数功能:将semid的信号量的
初始值设置为sem_v
*/
int set_semvalue(int sem_v,int semid)
{
   union semun sem_union;
    sem_union.val=sem_v;
    if(semctl(semid,0,SETVAL,sem_union)==-1)
       return 0;
    return 1;
}

//该函数将semid的信号量删除
void del_semvalue(int semid)
{
   union semun sem_un;
  semctl(semid,0,IPC_RMID,sem_un);
}

//该函数将semid信号量值加1
//1成功,0失败
int sem_post(int semid)
{
    struct sembuf sem_b;
      sem_b.sem_num=0;
      sem_b.sem_op=1;
      sem_b.sem_flg=SEM_UNDO;
      if(semop(semid,&sem_b,1)==-1)
       return 0;
       return 1;

}

//该函数将semid信号量值减1
//1成功,0失败
int sem_wait(int semid)
{

 struct sembuf sem_b;
      sem_b.sem_num=0;
      sem_b.sem_op=-1;
      sem_b.sem_flg=SEM_UNDO;
      if(semop(semid,&sem_b,1)==-1)
       return 0;
       return 1;
}


生产者代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using std::string;

union semun
 {
    int val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
};

string buf;//存储记录

//与共享内存有关的变量
int shmid=-1;// 共享内存的id
void * shm_re=(void *)0;
string * shm_records;// 保存共享内存的起始位置
int full=-1;
int empty=-1;
//函数接口说明
void daemon_start_task();//初始化函数

//封装的信号量处理接口
int set_semvalue(int sem_v,int semid);
void del_semvalue(int semid);
int sem_post(int semid);//加操作
int sem_wait(int semid);//减操作


int main(int argc,char * arg[])
{
  daemon_start_task();
  for(int i=0;i!=5;++i)
  {
    sem_wait(empty);
     *shm_records="come from production";
    sem_post(full);
    sleep(2);

  }
return 0;

}



void daemon_start_task()
{
    shmid=shmget((key_t)0x12356,sizeof(string),0666|IPC_CREAT);
    printf("shmid=%dn",shmid);
    shm_re=shmat(shmid,NULL,0);
   shm_records=(string *)shm_re;//此时可以使用共享内存
    printf("共享内存段在 %Xn",(int)shm_re);

    full=semget((key_t)0x8978,1,0666|IPC_CREAT);//只需要由消费者初始化一次即可

    empty=semget((key_t)0x74566,1,0666|IPC_CREAT);


}

//1成功,0失败
/*函数功能:将semid的信号量的
初始值设置为sem_v
*/
int set_semvalue(int sem_v,int semid)
{
   union semun sem_union;
    sem_union.val=sem_v;
    if(semctl(semid,0,SETVAL,sem_union)==-1)
       return 0;
    return 1;
}

//该函数将semid的信号量删除
void del_semvalue(int semid)
{
   union semun sem_un;
  semctl(semid,0,IPC_RMID,sem_un);
}

//该函数将semid信号量值加1
//1成功,0失败
int sem_post(int semid)
{
    struct sembuf sem_b;
      sem_b.sem_num=0;
      sem_b.sem_op=1;
      sem_b.sem_flg=SEM_UNDO;
      if(semop(semid,&sem_b,1)==-1)
       return 0;
       return 1;

}

//该函数将semid信号量值减1
//1成功,0失败
int sem_wait(int semid)
{

 struct sembuf sem_b;
      sem_b.sem_num=0;
      sem_b.sem_op=-1;
      sem_b.sem_flg=SEM_UNDO;
      if(semop(semid,&sem_b,1)==-1)
       return 0;
       return 1;
}



在执行过程中,让消费者先跑起来,那么它会在信号量那个阻塞自己,这个正常。
之后让生产者跑起来,此时又出现了经典的段错误。
我首先让消费者跑起来后:
ipcs -m 发现
------ Shared Memory Segments --------
key                  shmid         owner      perms      bytes      nattch     status  
0x00000000 720914     luoxiongwe 600        393216     2          dest         
0x00000000 753683     luoxiongwe 600        393216     2          dest         
0x00000000 786452     luoxiongwe 600        12288      2          dest         
0x00000000 819221     luoxiongwe 600        393216     2          dest         
0x00000000 1146902    luoxiongwe 600        393216     2          dest         
0x00000000 1310743    luoxiongwe 600        358620     2          dest         
0x00012356 1343512    luoxiongwe 666        4          1         
《unix高级环境编程》上面不是说由key去标识一个共享内存段吗?系统中怎么会后这么多的0x00000000?
我的进程的共享内存段的信息在最后一行。
我在中间输出了一些结果:
shmid=1343512
共享内存段在 B785B000
---------------------------------------
之后运行生产者进程,错误出现了。
shmid=1343512
共享内存段在 B7760000
段错误

他们的shmid竟然是相同的,而且共享段的起始地址居然不一样?
这是产生段错的原因吗?
《unix高级环境编程》说道:系统中的key值唯一标识一个共享内存段,shmid在不同的进程之间可以不同。
但是系统中的输出信息却表示key可以相同,但是shmid却不一样。

我在两个进程中的shmid是一样的。
请问这到底是怎么回事?
我的分数不多,而且问题有点长,请高手帮忙解答一下。谢谢了!
我现在在写一个日志系统,想利用共享内存实现进程中间的通信,
没有想到,预先写的一个小测试程序都有问题。 

|
0 的那些是IPC_PRIVATE 方式创建的吧?

    
 
 

您可能感兴趣的文章:

  • 网络编程中的共享内存问题,哪位高手可以帮忙解决啊?
  • 100分立给。请问在LINUX下开发嵌入式系统,会不会受64K基本内存的限制?这个问题很菜,请大家帮忙
  • 网络发送数据时 进程所占内存缓慢增加,直到系统内存耗尽而killed掉,[请大家帮忙]
  • 在suse linux下的程序,开辟一小块儿内存竟然用了400多个毫秒,高手帮忙分析一下
  • 内存泄漏,哪位老大帮忙看看阿
  • 如何检测内存泄露,请帮帮忙~~~~~~~~~~~~~~~~
  • 内存问题及 top 命令,郁闷了两个多月了.高手请帮忙.
  • 高手帮忙解释下linux如何对一个服务器的进程进行内存分配?
  • 牛人来帮忙解析一个shell脚本(用于统计一个进程的内存使用情况)
  • 帮忙看一下这三个服务器的内存使用情况是否正常,要命啊
  • Linux内存线性地址空间布局解析---的一些疑惑,大家帮忙解释解释
  • 惠普UNIX机器使用STL严重内存泄漏,高手帮忙压。
  • 不显示删除回复显示所有回复显示星级回复显示得分回复 父子进程间通信:1:共享内存2:信号量:父进程里请求信号量错误,高手帮忙
  • 关于全选的问题大家帮忙看看~
  • 我的Solaris启动不了了,请帮忙看看
  • iptables规则问题,请大家帮忙看看怎么回事
  • 各位帮忙看看网络配置问题
  • 大家帮忙看看错误如何解决
  • 高手帮忙看看cr3的值
  • 虚拟机扩容失败,下面提示的错误,帮忙看看
  • 才鸟问题,请帮忙看看
  • 那位朋友帮忙看看这是什么意思?多谢
  • 大吓帮忙看看?
  • 帮忙看看下面错误,怎样解决!!!
  • 一个200分的问题,大家帮忙看看:)谢了!关于Linux-PAM的
  • 一个shell的小问题,大家帮忙看看啊!
  • 请帮忙看看。
  • 请大家帮忙看看,编译内核后无法挂载root fs, 机器无法启动
  • 帮忙看看这是个什么错误啊?
  • 帮忙给个意见看看。
  • 大家帮忙看看,是什么问题
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 努力努力再努力,帮忙帮忙来帮忙!
  • 在servlet中有一个关于单引号输出的问题,请大家帮忙,帮忙,帮帮忙!!
  • 小问题,你一定能够帮忙!——菜鸟请求帮忙!!
  • 帮忙帮忙如何设置变量pathclass
  • 没人帮忙吗?我想用JAVA编一个像WINDOW中的画图软件,现在出现了如下问题,请各位老哥老姐帮帮忙
  • 帮帮忙!SCO OpenServer 5.0.5 的root用户口令丢了,怎么找回来啊,帮帮忙!!!!!!
  • 我用smartupload组件遇到问题了,请帮忙!!
  • webmail问题,请高手帮忙!!!谁会使用IMP 3.0????!!!
  • 脚本问题,帮忙
  • 高手帮忙解释
  • 求教求教,shell问题...各位大哥,帮忙下
  • 关于程序移植,请知道的帮忙,分会加的
  • DELL服务器,安装RedHat EAS3.0,装完了,连不上SSH。。。。。哪位大虾帮忙!!急啊 !!!!
  • 关于聊天室的若干疑问!!!请各位大虾帮忙!
  • NOSQL iis7站长之家
  • 请求各位帮忙,关于绘制图像
  • 帮忙找个工作。
  • 请帮忙推荐几个下载java电子书的网站,35分献上!
  • 我怎么不能编译servlet?请帮忙!!!谢谢!!!
  • 请问谁有weblogic6.1sp1的crack??大大加分!!请多帮忙!!!


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3