免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2129 | 回复: 0
打印 上一主题 下一主题

[应用] linux下共享内存的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-02 16:51 |只看该作者 |倒序浏览
本帖最后由 parrot18 于 2011-11-02 16:52 编辑

最近遇到一个很奇怪的问题,尝试父子进程之间共享内存进行进程间通信,使用的是SYSTEM V API,shmget系列
部分源代码如下:
  1. //下面是顺序存储队列和队列一些操作的定义,准备使用这个队列来进行进程间的信息存取
  2. typedef struct queue
  3. {
  4.         unsigned char buffer[64][128];
  5.         int front, rear;
  6.         int buf_size;
  7. }QUEUE;

  8. //初始化队列
  9. void initQueue(QUEUE* cache)
  10. {
  11.         cache->front = 0;
  12.         cache->rear = 0;
  13.         cache->buf_size = 64;
  14.         int i;
  15.         for(i=0;i<cache->buf_size;i++)
  16.         {
  17.                 memset(cache->buffer[i], 0, cache->buf_size);
  18.         }
  19. }
  20. //返回队首元素不改变队列状态
  21. int outQueue(QUEUE* cache, unsigned char* buf)
  22. {
  23.         sem_wait(sem_cache);
  24.         if(cache->front == cache->rear)
  25.                 {
  26.                         printf("the queue is empty!\n");
  27.                         return -1;
  28.                 }       
  29.         memcpy(buf, cache->buffer[(cache->front + 1) % cache->buf_size], cache->buf_size);
  30.         sem_post(sem_cache);
  31.         return 0;
  32. }
  33. //删除队首元素
  34. int delFront(QUEUE* cache)
  35. {
  36.         sem_wait(sem_cache);
  37.         if(cache->front == cache->rear)
  38.                 {
  39.                         printf("the queue is empty!\n");
  40.                         return -1;
  41.                 }
  42.         cache->front = (cache->front + 1) % cache->buf_size ;
  43.         memset(cache->buffer[cache->front], 0, cache->buf_size);
  44.         sem_post(sem_cache);
  45.         return 0;
  46. }
  47. //插入元素
  48. int enQueue(QUEUE* cache, unsigned char* buf)
  49. {
  50.         sem_wait(sem_cache);
  51.         if(((cache->rear + 1) % cache->buf_size) == cache->front)
  52.                 {
  53.                         printf("the queue is full!\ndelete first node\n");
  54.                         cache->front = (cache->front + 1) % cache->buf_size ;
  55.                         memset(cache->buffer[cache->front], 0, cache->buf_size);
  56.                 }
  57.         cache->rear = (cache->rear + 1) % cache->buf_size;
  58.         memcpy(cache->buffer[cache->rear], buf, cache->buf_size);
  59.         sem_post(sem_cache);
  60.         return 0;
  61. }
  62. //主程序利用信号灯进行共享内存读写的同步
  63. int main()
  64. {
  65.        
  66. /*创建信号灯*/
  67.         sem_cache=sem_open(SEM_NAME,O_CREAT,0666,1);
  68.         sem_close(sem_cache);
  69.         sem_unlink(SEM_NAME);
  70.         sem_cache=sem_open(SEM_NAME,O_CREAT,0666,1);//信号灯初始值为1
  71.        
  72.         int flag = 0;
  73.         sem_getvalue(sem_cache, &flag);//问题1:如果不执行这步操作,信号灯初值居然为0...这段信号灯代码用了N年了,就今天这次出问题,不知是为什么。。。
  74.         printf("sem:%d\n", flag);
  75.         unsigned char send_buf[128], read_buf[128];
  76.         memset(send_buf, 0, 128);
  77.         memset(read_buf, 0, 128);
  78.         QUEUE* app_cache;
  79.         int shmid;
  80.         shmid = shmget((key_t)118, 8192, IPC_CREAT|0666);
  81.         if(shmid == -1)
  82.                 {
  83.                         perror("shmget");
  84.                         return -1;
  85.                 }
  86.         app_cache = (QUEUE* )shmat(shmid, NULL, 0);
  87.         if(app_cache == NULL)
  88.                 {
  89.                         perror("shmat");
  90.                         return -1;
  91.                 }
  92.         initQueue(app_cache);
  93.         send_buf[0] = 252;
  94.         send_buf[1] = 51;
  95.         send_buf[2] = 53;
  96.         send_buf[3] = 49;
  97.         send_buf[4] = 54;
  98.         send_buf[5] = 57;
  99.         send_buf[6] = 51;
  100.         send_buf[7] = 48;
  101.         send_buf[8] = 51;
  102.         send_buf[9] = 49;
  103.         send_buf[10] = 49;
  104.         send_buf[11] = 49;
  105.         send_buf[12] = 48;
  106.         send_buf[13] = 55;
  107.         send_buf[14] = 51;
  108.         send_buf[15] = 52;
  109.         send_buf[16] = 0;
  110.         send_buf[17] = 21;
  111.         send_buf[18] = 6;
  112.         send_buf[19] = 0;
  113.         send_buf[20] = 214;
  114.         send_buf[21] = 13;
  115.         send_buf[22] = 0;
  116.         send_buf[23] = 158;
  117.         send_buf[24] = 52;
  118.         send_buf[25] = 7;
  119.         send_buf[26] = 0;
  120.         send_buf[27] = 160;
  121.        
  122.         enQueue(app_cache, send_buf);//插入信息       
  123.         enQueue(app_cache, send_buf);//插入信息
  124.         outQueue(app_cache, read_buf);//读取信息但是队列状态不变
  125.         delFront(app_cache);//删除头结点
  126.         printf("%d\n",app_cache->rear - app_cache->front);//打印队首队尾信息,不论这句话出现在哪儿..只要一访问app_cache->front,它的值就变了!!...正常此处应该是2-1 = 1  访问完之后 front 应该是1  rear是2 但是...gdb调试打印出来的front是2069..有时候甚至是几万几千...然后之后的enQueue操作就有可能溢出、段错误...很郁闷,不论在哪里,只要一访问完front,front的值立马就变了...哪怕只是打印一下...
  127.         shmctl(shmid, IPC_RMID, 0);
  128. }

复制代码
请大家帮忙指点指点这是为什么。。。谢谢。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP