linux c ++同步方法,包括inter和intra进程

时间:2017-02-15 23:51:30

标签: c++ c linux multithreading

当我开发用于为每个数据库添加书签信息的注册表系统(c / c ++,2.6.32-642.6.2.el6.x86_64#1 SMP)时,会出现这个问题,这需要锁定内部和内部处理。通常,lockf()flock()fcntl()是进程间锁定的明显候选者,但后来我发现它们不能按预期进行进程内锁定(同一个多线程)处理)。

我使用以下程序对其进行了测试:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>    /* For O_RDWR */
#include <unistd.h>   /* For open(), creat() */
#include <errno.h>

int counter = 0;

void* counterThread(void* ptr)
{
    int lockfd = 0;
    int tmpCounter = 0;

    lockfd = open("/tmp/lockfile.txt", O_CREAT|O_WRONLY, 0666);
    if(lockfd == -1)
    {
        printf("lockfile could not be created, errno:%d\n", errno);
        return NULL;
    }

    if(lockf(lockfd, F_LOCK, 0) == -1)
    {
        printf("lockfile could not be locked, errno:%d\n", errno);
        return NULL;
    }

    counter++;
    tmpCounter = counter;

    if(lockf(lockfd, F_ULOCK, 0) == -1)
    {
        printf("lockfile could not be unlocked, errno:%d\n", errno);
        return NULL;
    }
    close(lockfd);

    printf("counter is %d, lockfile is %d\n", tmpCounter, lockfd);
}

int main()
{
    int threadNum = 30000;
    pthread_t threads[30000];
    int i = 0;
    int rv = 0;
    for(; i < threadNum; i++)
    {
        rv = pthread_create( &threads[i], NULL, &counterThread, NULL);
        if(rv != 0)
        {
            printf("failed to create pthread %d\n", i);
            return -1;
        }
    }
    for(i = 0; i < threadNum; i++)
        pthread_join(threads[i], NULL);

    return 0;
}

输出结果为:

counter is 1, lockfile is 4
counter is 2, lockfile is 3
counter is 3, lockfile is 5
counter is 4, lockfile is 6
counter is 7, lockfile is 4
...
counter is 29994, lockfile is 3
counter is 29995, lockfile is 3
counter is 29996, lockfile is 3
counter is 29997, lockfile is 3
counter is 29998, lockfile is 3

输出序列是随机的,有时会遗漏一些数字,这意味着确实存在竞争条件。我认为原因可能是在同一进程中为同一个文件打开的fd以某种方式进行了优化以便重用。因为所有这些锁定机制都是以fd的粒度实现的,所以在这种情况下锁定不起作用。

鉴于背景,我想问下列问题:

  1. 是否有任何方法可以强制打开将不同线程的不同fd返回到同一进程以使锁定工作?
  2. 在Linux中是否有任何良好实践或方便的API来进行内部和内部进程锁定?我能想到的是以下实现它的方法(尚未验证),但我想知道一些更简单的方法:

    (1)实现互斥和信号量以序列化对关键资源的所有这些lockfile API的访问

    (2)shm_open共享内存,在不同进程中对其进行mmap,并在内部添加信号量/互斥锁以锁定关键资源

  3. 提前致谢:)

0 个答案:

没有答案