免费注册 查看新帖 |

Chinaunix

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

[C] help如何使用信号量避免文件读写冲突(基本功能实现,但仍有疑惑) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-11-22 14:51 |只看该作者 |倒序浏览
2个进程同时读写一个文件会产生冲突
我想利用信号量来控制
我设想的步骤:

1.create一个信号量
2.P操作
3.读写文件
4.V操作

我临时网络上找的一些信号量的知识,没怎么看明白
希望哪位前辈能抽时间点拨下
能否给个伪代码
先谢谢了!

我使用的系统是:Linux test237 2.6.9-55.ELsmp #1 SMP Fri Apr 20 16:36:54 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux

参考 unix网络编程:卷2 255页的程序,锁的功能已经实现了,但是遇到2个问题不明白
1. 该行代码有疑惑 if(arg.buf->sem_otime != 0)    //这里sem_otime == 0(按书上说的如果该值不为0,表示创建该信号灯的进程已对它初始化,继续为0的情况很罕见..)
2:/tmp/sem 文件是我手动创建的..这样对吗?

  1. #include <sys/ipc.h>
  2. #include <sys/sem.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <errno.h>
  6. #include <semaphore.h>

  7. #define LOCK_PATH       "/tmp/sem"
  8. #define MAX_TRIES       10      
  9. #define repline() do{ printf("%d", __LINE__); fflush(stdout); }while(0)

  10. union semun {
  11.         int     val;   
  12.         struct semid_ds *buf;
  13.         unsigned short  *array;
  14. };

  15. int             semid, initflag;
  16. struct sembuf   postop, waitop;


  17. int
  18. my_lock(void)
  19. {
  20.         int             oflag, i;
  21.         key_t           semkey;
  22.         union semun     arg;   
  23.         struct semid_ds seminfo;

  24.         if(initflag == 0) {
  25.                 if( (semkey = ftok(LOCK_PATH, 0)) == -1) {
  26.                         repline();
  27.                         perror("[ftok]");
  28.                         return -1;
  29.                 }      
  30.                         
  31.                 oflag = IPC_CREAT | IPC_EXCL | 0777;
  32.                 if( (semid = semget(semkey, 1, oflag)) >=0) {
  33.                         arg.val = 1;
  34.                         if(semctl(semid, 0, SETVAL, arg) < 0) {
  35.                                 repline();
  36.                                 perror("[semctl]");
  37.                         }      
  38.                 } else if(errno == EEXIST) {
  39.                         if( (semid = semget(semkey, 1, 0777)) < 0) {
  40.                                 repline();
  41.                                 perror("[semget]");
  42.                                 return -1;
  43.                         }      
  44.                         arg.buf = &seminfo;
  45.                         for(i = 0; i < MAX_TRIES; i++) {
  46.                                 if(semctl(semid, 0, IPC_STAT, arg) < 0) {
  47.                                         repline();
  48.                                         perror("[semctl]");
  49.                                         return -1;
  50.                                 }
  51.                             if(arg.buf->sem_otime != 0)    //这里sem_otime == 0
  52.                                         goto init;
  53.                                 sleep(1);
  54.                         }
  55.                         repline();
  56.                         printf("time out\n");
  57.                         return -1;
  58.                 } else
  59.                         repline();
  60.                         return -1;
  61. init:
  62.         initflag = 1;
  63.         postop.sem_num = 0;
  64.         postop.sem_op = 1;
  65.         postop.sem_flg = SEM_UNDO;

  66.         waitop.sem_num = 0;
  67.         waitop.sem_op = -1;
  68.         waitop.sem_flg = SEM_UNDO;
  69.         }
  70.         if( semop(semid, &waitop, 1) < 0) {
  71.                 repline();
  72.                 perror("[semop]");
  73.                 return -1;
  74.         }

  75.         return 0;
  76. }

  77. int
  78. my_unlock(void)
  79. {
  80.         if( semop(semid, &postop, 1) < 0) {
  81.                 repline();
  82.                 perror("[semop]");
  83.                 return -1;
  84.         }
  85.         return 0;
  86. }

  87. int
  88. main()
  89. {
  90.          my_lock();
  91.          /*读写文件*/
  92.          my_unlock();
  93.          return 0;
  94. }

复制代码

[ 本帖最后由 车太咸 于 2007-11-23 15:10 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-11-22 14:58 |只看该作者

论坛徽章:
0
3 [报告]
发表于 2007-11-22 15:02 |只看该作者
是不是一个进程读写完了以后,用个kill发一个SIGUSER1,信号给另一个进程,那个进程只有捕获到这个信号才可以读写,反之亦然。
ps:为什么不用锁机制?

论坛徽章:
0
4 [报告]
发表于 2007-11-22 15:10 |只看该作者
原帖由 zijian1984 于 2007-11-22 15:02 发表
是不是一个进程读写完了以后,用个kill发一个SIGUSER1,信号给另一个进程,那个进程只有捕获到这个信号才可以读写,反之亦然。
ps:为什么不用锁机制?

我理解的意思:
先建立一个信号量给它赋值0

进程读写文件前判断信号量的值
如果为1就等待
如果为0就将值改成1
然后进行文件读写操作
文件操作完毕后将信号量值改成0

在我目前的情况下用锁不方便,程序变动要大点

ps:貌似技术区域很冷清 水区很火爆...

[ 本帖最后由 车太咸 于 2007-11-22 15:11 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2007-11-22 15:17 |只看该作者
网络编程的书没带
下了个pdf的又不全

继续啃
麻烦路过的达人点拨下 不胜感激

论坛徽章:
0
6 [报告]
发表于 2007-11-22 15:17 |只看该作者
你的思路没啥问题
实现吧

论坛徽章:
0
7 [报告]
发表于 2007-11-22 15:20 |只看该作者
原帖由 zi_ji 于 2007-11-22 15:17 发表
你的思路没啥问题
实现吧

就是不知道怎么实现....

那几个函数我很晕
semget
semctl
看man手册 e文烂 晕忽忽的

能告诉我每个步骤用哪些函数吗?

论坛徽章:
0
8 [报告]
发表于 2007-11-22 15:26 |只看该作者
用semget可以建立一个信号量
用semctl可以给信号量赋值
那判断信号量的值要什么函数实现呢?怎么使进程等待?
还有就是万一进程在信号量的值没有复位前就异常中断了,那怎么办?

论坛徽章:
0
9 [报告]
发表于 2007-11-22 15:32 |只看该作者
两个进程是两个程序吗.....
可以考虑用管道
进程A阻塞住收到进程B的消息可以读文件...
然后进程B在阻塞住收到进程A的消息,在读文件

论坛徽章:
0
10 [报告]
发表于 2007-11-22 15:34 |只看该作者
原帖由 ruchong 于 2007-11-22 15:32 发表
两个进程是两个程序吗.....
可以考虑用管道
进程A阻塞住收到进程B的消息可以读文件...
然后进程B在阻塞住收到进程A的消息,在读文件

是2个独立的程序

谢谢关注...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP