免费注册 查看新帖 |

Chinaunix

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

[Linux] 关于LINUX 信号量 与 usleep 引发重复上锁的问题求教 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-10-10 15:24 |只看该作者 |倒序浏览
在研究学习信号量的时候,发现了一个奇怪了问题,如果在信号量的处理过程中调用usleep睡眠等待,那么会出现,进程A上锁后,进程B也可以上锁(在进程A没有解锁的条件下),但是如果去掉了usleep,是可以正常运行的。代码如下求大神指导,谢谢!!!

#include <basefun.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#define SEM_KEY 8999
#define SVSEM_MODE 0644

union semun {
        int val;
        struct semid_ds *buf;
        unsigned short *array;
        struct seminfo *__buf;
};

int sem_init();
int sem_lock(int semid);
int sem_unlock(int semid);
int sem_delete(int semid);
int sem_deal(int semid);
int sem_count(int semid);

void test_wait(int loop);

int main()
{
        int rs, semid;
       
        semid = sem_init();
        _CHECK_RS(semid, -1, -1);

        if (0 == fork()) {
                rs = sem_deal(semid);
                _CHECK_RS(rs, -1, -1);
                return 0;
        }
       
        rs = sem_deal(semid);
        _CHECK_RS(rs, -1, -1);

        GET_INPUT;
        sem_delete(semid);

        return 0;
}

int sem_init() {

        int rs, semid;
        int flag = IPC_CREAT | IPC_EXCL | SVSEM_MODE;
        sembuf sb;

        semid = semget(SEM_KEY, 1, flag);
        _CHECK_RS(semid, -1, -1);
       
        memset(&sb, 0, sizeof(sb));
        sb.sem_num = 0;
        sb.sem_op = 1;
        sb.sem_flg = SEM_UNDO;

        rs = semop(semid, &sb, 1);
        _CHECK_RS(rs, -1, 1);

        return semid;
}

int sem_delete(int semid) {

        int rs;
        rs = semctl(semid, 0, IPC_RMID, NULL);
        _CHECK_RS(rs, -1, -1);
        return 0;
}

int sem_lock(int semid) {

        int rs;
        sembuf sb;

        memset(&sb, 0, sizeof(sb));

        sb.sem_num = 0;
        sb.sem_op = -1;
        sb.sem_flg = SEM_UNDO;

        rs = semop(semid, &sb, 1);
        _CHECK_RS(rs, -1, -1);

        return 0;
}

int sem_unlock(int semid) {

        int rs;
        sembuf sb;

        memset(&sb, 0, sizeof(sb));

        sb.sem_num = 0;
        sb.sem_op = 1;
        sb.sem_flg = SEM_UNDO;

        rs = semop(semid, &sb, 1);
        _CHECK_RS(rs, -1, -1);

        return 0;
}

int sem_deal(int semid) {

        int i, rs;
        struct timespec stime = {0, 100};
       
        for (i = 0; i < 5; i++) {

                rs = sem_lock(semid);       
                _CHECK_RS(rs, -1, -1);
                P("[%ld] lock succeed, count[%d] ...\n", getpid(), sem_count(semid));

                rs = sem_unlock(semid);
                _CHECK_RS(rs, -1, -1);       
                P("[%ld] unlock succeed, count[%d] ...\n", getpid(), sem_count(semid));

                usleep(100);
        }

        return 0;
}

int sem_count(int semid) {

        union semun arg;
        struct semid_ds seminfo;
        arg.buf = &seminfo;

        return semctl(semid, 0, GETVAL, arg);
}

void test_wait(int loop) {

        for (int i = 0; i < loop; i++)
                ;
}

论坛徽章:
0
2 [报告]
发表于 2014-10-16 13:39 |只看该作者
楼主上锁后马上就解锁了,usleep 是在sem_unlock之后做的啊,
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP