使用文件锁定的进程之间的条件变量

condtional variable among processes using file lock

本文关键字:进程 之间 条件 变量 锁定 文件 文件锁      更新时间:2023-10-16

我想同步多个进程。我想出两种可能的方法:1. 文件锁定2. 使用共享内存的进程之间的互斥锁

但是共享内存有点复杂,我不确定我是否可以使用它而不会对进程中运行的其他模块产生副作用。所以我更喜欢文件锁定方法。

但是文件锁定只提供shared lockexclusive lock,没有条件变量(据我所知..(。还有其他选择吗?还是我别无选择,只能共享内存?

添加:

我想要一个条件变量的原因是我想限制共享锁持有人的数量

我想出了一种仅使用简单的独占文件锁的方法,如下面的伪代码所示:

RETRY:
file_lock.unique_lock();
if (counter == MAX_PROCESS_ALLOW) {
  file_lock.unlock();
  goto RETRY;
}
// successful get into the pool
++counter;
file_lock.unlock();
// do some thing here
// exit the pool
file_lock.unique_lock();
--counter;
file_lock.unlock();

但这种方法的问题是繁忙的查询。或者我可以选择睡觉,但很难确定睡眠时间......

考虑使用,

sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
int sem_wait(sem_t *sem);
int sem_getvalue(sem_t *sem, int *sval);
int sem_post(sem_t *sem);
int sem_close(sem_t *sem);
int sem_unlink(const char *name);

任何具有权限的进程都可以修改计数,这将释放等待锁定的进程。 这将允许进行复杂的评估。 在 sem_open(...( 中设置"值"将确定可以共享锁的进程数。 有关详细信息,请参见手册页。 有许多支持功能。 以下代码是一个示例。 如果您构建并执行它超过 4 次,那么您会看到较晚的启动者等到较早的启动者完成。

请注意,/dev/shm/sem.test_sem 是 Debian Buster 下与 Linux 内核的共享资源。 代码示例如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>           /* For O_* constants */
#include <sys/stat.h>        /* For mode constants */
#include <semaphore.h>
// For Debian Buster, the shared sem is found at /dev/shm/sem.test_sem
int main(int argc, char *argv[])
{   printf("Startingn");
    sem_t *sem;
    sem = sem_open("/test_sem", O_CREAT, 0600, 3);q
    if(sem == SEM_FAILED){
        printf("SEM_FAILEDn");
        return -1;
    }
    // sem_unlink("/test_sem"); return 0;  // Use this to remove /dev/shm/sem.test_sem
    sem_wait(sem);
    for(int i = 0; i < 20 ; i++){
        int current_sem_value;
        int error_code = sem_getvalue(sem, &current_sem_value);
        //printf("sem_getvalue return value: %dn", error_code);
        if(error_code){
            printf("Sem not valid!n");
        }
        printf("Sem count: %d n", current_sem_value);
        fflush(stdout);
        sleep(1);
    }
    sem_post(sem);
    sem_close(sem);
    return 0;
}

请注意,sem_unlink(...( 将从文件系统中删除信号量。