Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有FIFO等待队列的Linux同步_Linux_Synchronization_Pthreads_Mutex_Semaphore - Fatal编程技术网

具有FIFO等待队列的Linux同步

具有FIFO等待队列的Linux同步,linux,synchronization,pthreads,mutex,semaphore,Linux,Synchronization,Pthreads,Mutex,Semaphore,Linux中是否存在等待队列为FIFO的锁?这看起来很明显,但我刚刚发现pthread互斥体不是FIFO,信号量显然也不是FIFO(我正在研究内核2.4(家庭作业)) Linux是否有带FIFO等待队列的锁,或者是否有一种简单的方法可以使用现有机制来实现 如果你问的是我认为你在问的问题,那么简短的回答是否定的。线程/进程由OS调度程序控制。一个随机线程将获得锁,其他线程不会。如果你使用计数信号量,可能不止一个,但这可能不是你要问的 你可能想看看,但这不会让你达到我怀疑你想去的地方 您可能会编写一

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


Linux是否有带FIFO等待队列的锁,或者是否有一种简单的方法可以使用现有机制来实现

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

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

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


很可能你只是用错误的方式思考问题。您可能希望描述您的目标并获得更好的建议。

下面是一种创建简单排队“票证锁”的方法,它是基于pthreads原语构建的。它应该给你一些想法:

#include <pthread.h>

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);
}
#包括
typedef结构票据锁{
pthread_cond_t cond;
pthread_mutex_t mutex;
无符号长队列头、队列尾;
}车票锁;
#定义票据\锁\初始值设定项{PTHREAD\ COND\初始值设定项,PTHREAD\ MUTEX\初始值设定项}
无效票锁(票锁*票)
{
未签名的长队;
pthread_mutex_lock(&ticket->mutex);
queue_me=ticket->queue_tail++;
while(排队我!=车票->排队头)
{
pthread_cond_wait(&ticket->cond,&ticket->mutex);
}
pthread_mutex_unlock(&ticket->mutex);
}
无效车票解锁(车票锁定车票)
{
pthread_mutex_lock(&ticket->mutex);
票证->队列头++;
pthread_cond_广播(&ticket->cond);
pthread_mutex_unlock(&ticket->mutex);
}

我最近有一个类似的需求,除了处理多个流程。以下是我的发现:

  • 如果您需要100%正确的FIFO顺序,请使用caf

  • 如果你对99%的简单性感到满意,那么一个信号量或互斥量实际上可以做得很好

票证锁可以跨进程工作:
您需要使用共享内存,处理共享互斥体和条件变量,处理在互斥体锁定(->健壮互斥体)的情况下死亡的进程。。。这有点过分了,我所需要的是不同的实例不能在同一时间得到安排,而且顺序要公平

使用信号量:

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 */
}
static sem\u t*sem=NULL;
void fifo_init()
{
sem=sem_open(“/server_fifo”,O_CREAT,0600,1);
如果(sem==sem_失败)失败(“sem_打开”);
}
无效fifo_锁()
{
INTR;
结构timespects;
如果(clock_gettime(clock_REALTIME,&ts)=-1)失败(“clock_gettime”);
ts.tv_秒+=5;/*5s超时*/
while((r=sem\u timedwait(sem,&ts))==-1&&errno==EINTR)
继续;/*如果中断,请重新启动*/
如果(r==0)返回;
如果(errno==ETIMEDOUT)fprintf(stderr,“超时…\n”);
否则失败(“sem_timedwait”);
}
无效fifo_解锁()
{
/*如果我们最终得到了不止一个标记,不要增加信号量*/
int-val;

if(sem_getvalue(sem,&val)==0&&val我有一个服务器客户端的情况,服务器需要以这样的方式保存日志文件,即写入日志文件不会干扰其I/O,这意味着服务器clent连接线程不能等待,因为它正在等待另一个这样的线程锁定的日志的互斥锁失败。我正在考虑抛出每个线程尝试使用单独的“写入日志文件”线程可以在不干扰其父线程的情况下等待。日志文件中的消息可能会混淆,但必须保持每个连接的正确时间顺序,这就是我需要FIFO的原因。设置队列。c-s连接将其日志信息写入队列。单独的线程读取队列并写入文件。您仍然必须获取re是队列上的一个锁,但除非您知道其他情况,否则这应该是无关的。获取队列锁的时间量将与文件和网络I/O的相对速度相形见绌。因为任何给定的c-s线程都是按顺序写入队列的,所以您的日志输出也将按顺序写入每个线程。是的,这就是我想要避免的(需要比FIFIO锁更多的更改),但我想我没有选择了。。。