Linux synchronization with FIFO waiting queue

后端 未结 3 855
别跟我提以往
别跟我提以往 2020-12-15 02:01

Are there locks in Linux where the waiting queue is FIFO? This seems like such an obvious thing, and yet I just discovered that pthread mutexes aren\'t FIFO, and semaphores

3条回答
  •  情深已故
    2020-12-15 02:28

    I had a similar requirement recently, except dealing with multiple processes. Here's what I found:

    • If you need 100% correct FIFO ordering, go with caf's pthread ticket lock.

    • If you're happy with 99% and favor simplicity, a semaphore or a mutex can do really well actually.

    Ticket lock can be made to work across processes:
    You need to use shared memory, process-shared mutex and condition variable, handle processes dying with the mutex locked (-> robust mutex) ... Which is a bit overkill here, all I need is the different instances don't get scheduled at the same time and the order to be mostly fair.

    Using a semaphore:

    static sem_t *sem = NULL;
    
    void fifo_init()
    {
        sem = sem_open("/server_fifo", O_CREAT, 0600, 1);
        if (sem == SEM_FAILED)  fail("sem_open");
    }
    
    void fifo_lock()
    {
        int r;
        struct timespec ts;
        if (clock_gettime(CLOCK_REALTIME, &ts) == -1)  fail("clock_gettime");
        ts.tv_sec += 5;     /* 5s timeout */
    
        while ((r = sem_timedwait(sem, &ts)) == -1 && errno == EINTR)
            continue;       /* Restart if interrupted */
        if (r == 0)  return;
    
        if (errno == ETIMEDOUT) fprintf(stderr, "timeout ...\n");
        else                    fail("sem_timedwait");
    }
    
    void fifo_unlock()
    {
        /* If we somehow end up with more than one token, don't increment the semaphore... */
        int val;
        if (sem_getvalue(sem, &val) == 0 && val <= 0)
            if (sem_post(sem))  fail("sem_post");
        usleep(1);  /* Yield to other processes */
    }
    

    Ordering is almost 100% FIFO.

    Note: This is with a 4.4 Linux kernel, 2.4 might be different.

提交回复
热议问题