首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >linux上的msemaphore?

问linux上的msemaphore?
EN

Stack Overflow用户
提问于 2009-05-07 20:42:34
回答 3查看 537关注 0票数 2

AIX (如果有人关心的话,还有HPUX )有一个很好的小特性,称为msemaphores,它可以轻松地同步由多个进程共享的内存映射文件的细粒度片段(例如记录)。有没有人意识到linux中有一些类似的东西?

为了清楚起见,通过相关链接here描述了msemaphore函数。

EN

回答 3

Stack Overflow用户

发布于 2009-05-08 02:25:52

如果sem_init(3)的第二个参数"pshared“为真,则可以将POSIX semaphores放在进程之间共享的内存中。这似乎和msem所做的是一样的。

代码语言:javascript
复制
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
int main() {
    void *shared;
    sem_t *sem;
    int counter, *data;
    pid_t pid;
    srand(time(NULL));
    shared = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
            MAP_ANONYMOUS | MAP_SHARED, -1, 0);
    sem_init(sem = shared, 1, 1);
    data = shared + sizeof(sem_t);
    counter = *data = 0;
    pid = fork();
    while (1) {
        sem_wait(sem);
        if (pid)
            printf("ping>%d %d\n", data[0] = rand(), data[1] = rand());
        else if (counter != data[0]) {
            printf("pong<%d", counter = data[0]);
            sleep(2);
            printf(" %d\n", data[1]);
        }
        sem_post(sem);
        if (pid) sleep(1);
    }
}

这是一个相当愚蠢的测试,但它是有效的:

代码语言:javascript
复制
$ cc -o test -lrt test.c
$ ./test
ping>2098529942 315244699
pong<2098529942 315244699
pong<1195826161 424832009
ping>1195826161 424832009
pong<1858302907 1740879454
ping>1858302907 1740879454
ping>568318608 566229809
pong<568318608 566229809
ping>1469118213 999421338
pong<1469118213 999421338
ping>1247594672 1837310825
pong<1247594672 1837310825
ping>478016018 1861977274
pong<478016018 1861977274
ping>1022490459 935101133
pong<1022490459 935101133
...

因为信号量是在两个进程之间共享的,所以pong不会从ping获得交错数据,尽管sleep是。

票数 1
EN

Stack Overflow用户

发布于 2009-05-08 02:39:52

这可以使用POSIX共享内存互斥锁来完成:

代码语言:javascript
复制
pthread_mutexattr_t attr;
int pshared = PTHREAD_PROCESS_SHARED;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, &pshared);

pthread_mutex_init(&some_shared_mmap_structure.mutex, &attr);
pthread_mutexattr_destroy(&attr);

现在,您可以使用普通的pthread_mutex_lock()等调用,从映射了&some_shared_mmap_structure.mutex的多个进程中解锁和锁定它。

实际上,您甚至可以从以下方面实现msem API:(未测试)

代码语言:javascript
复制
struct msemaphore {
    pthread_mutex_t mut;
};

#define MSEM_LOCKED 1
#define MSEM_UNLOCKED 0
#define MSEM_IF_NOWAIT 1

msemaphore *msem_init(msemaphore *msem_p, int initialvalue) {
    pthread_mutex_attr_t attr;
    int pshared = PTHREAD_PROCESS_SHARED;

    assert((unsigned long)msem_p & 7 == 0); // check alignment

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_setpshared(&attr, &pshared); // might fail, you should probably check
    pthread_mutex_init(&msem_p->mut, &attr); // never fails
    pthread_mutexattr_destroy(&attr);

    if (initialvalue)
        pthread_mutex_lock(&attr);

    return msem_p;
}

int msem_remove(msemaphore *msem) {
    return pthread_mutex_destroy(&msem->mut) ? -1 : 0;
}

int msem_lock(msemaphore *msem, int cond) {
    int ret;
    if (cond == MSEM_IF_NOWAIT)
        ret = pthread_mutex_trylock(&msem->mut);
    else
        ret = pthread_mutex_lock(&msem->mut);

    return ret ? -1 : 0;
}

int msem_unlock(msemaphore *msem, int cond) {
    // pthreads does not allow us to directly ascertain whether there are
    // waiters. However, a unlock/trylock with no contention is -very- fast
    // using linux's pthreads implementation, so just do that instead if
    // you care.
    //
    // nb, only fails if the mutex is not initialized
    return pthread_mutex_unlock(&msem->mut) ? -1 : 0;
}
票数 1
EN

Stack Overflow用户

发布于 2009-05-07 20:48:28

在Linux下,您也许能够使用SysV共享内存实现您想要的东西;快速搜索this (rather old) guide可能会有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/836925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档