热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux与FIFO等待队列同步-LinuxsynchronizationwithFIFOwaitingqueue

AretherelocksinLinuxwherethewaitingqueueisFIFO?Thisseemslikesuchanobviousthing,and

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 apparently aren't FIFO either (I'm working on kernel 2.4 (homework))...

在Linux中有等待队列是FIFO的锁吗?这看起来很明显,但我刚发现pthread互斥量不是FIFO,信号量显然也不是FIFO(我正在研究内核2.4(家庭作业))...

Does Linux have a lock with FIFO waiting queue, or is there an easy way to make one with existing mechanisms?

Linux是否具有FIFO等待队列的锁定,或者是否有一种简单的方法来使用现有机制?

3 个解决方案

#1


3  

Here is a way to create a simple queueing "ticket lock", built on pthreads primitives. It should give you some ideas:

这是一种基于pthreads基元创建简单排队“票证锁”的方法。它应该给你一些想法:

#include 

typedef struct ticket_lock {
    pthread_cond_t cond;
    pthread_mutex_t mutex;
    unsigned long queue_head, queue_tail;
} ticket_lock_t;

#define TICKET_LOCK_INITIALIZER { PTHREAD_COND_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }

void ticket_lock(ticket_lock_t *ticket)
{
    unsigned long queue_me;

    pthread_mutex_lock(&ticket->mutex);
    queue_me = ticket->queue_tail++;
    while (queue_me != ticket->queue_head)
    {
        pthread_cond_wait(&ticket->cond, &ticket->mutex);
    }
    pthread_mutex_unlock(&ticket->mutex);
}

void ticket_unlock(ticket_lock_t *ticket)
{
    pthread_mutex_lock(&ticket->mutex);
    ticket->queue_head++;
    pthread_cond_broadcast(&ticket->cond);
    pthread_mutex_unlock(&ticket->mutex);
}

#2


4  

If you are asking what I think you are asking the short answer is no. Threads/processes are controlled by the OS scheduler. One random thread is going to get the lock, the others aren't. Well, potentially more than one if you are using a counting semaphore but that's probably not what you are asking.

如果你问我认为你在问什么,简短的回答是否定的。线程/进程由OS调度程序控制。一个随机线程将获得锁定,其他线程则不会。好吧,如果你使用计数信号量,可能不止一个,但这可能不是你要求的。

You might want to look at pthread_setschedparam but it's not going to get you where I suspect you want to go.

你可能想看看pthread_setschedparam,但它不会让你到达我怀疑你想去的地方。

You could probably write something but I suspect it will end up being inefficient and defeat using threads in the first place since you will just end up randomly yielding each thread until the one you want gets control.

你可能会写一些东西,但我怀疑它最终会变得低效并且首先使用线程失败,因为你最终会随机产生每个线程直到你想要的那个获得控制权。

Chances are good you are just thinking about the problem in the wrong way. You might want to describe your goal and get better suggestions.

机会很好你只是以错误的方式思考问题。您可能想要描述您的目标并获得更好的建议。

#3


0  

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.

    如果您需要100%正确的FIFO订购,请使用caf的pthread门票锁。

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

    如果你对99%感到高兴并且喜欢简单,那么信号量或互斥量实际上可以做得非常好。

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.

订购几乎是100%的FIFO。

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

注意:这是一个4.4 Linux内核,2.4可能会有所不同。


推荐阅读
author-avatar
彼岸花2011的冬天_290
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有