Linux多线程同步之消息队列有何特点

Linux多线程同步之消息队列有何特点,第1张

消息队列消息的链表,存放在内核中并有消息队列标示符标示。

msgget用于创建一个新队列或打开一个现存的队列。msgsnd将新消息加入到消息队列中;每个

消息包括一个long型的type;和消息缓存;msgrcv用于从队列中取出消息;取消息很智能,不一定先进先出

①msgget,创建一个新队列或打开一个现有队列

#include

int msgget ( key_t key, int flag );

//成功返回消息队列ID;错误返回-1

②msgsnd: 发送消息

#include

int msgsnd( int msgid, const void* ptr, size_t nbytes, int flag )

//成功返回0,错误返回-1

a:

flag可以指定为IPC_NOWAIT

若消息队列已满,则msgsnd立即出错返回EABAIN;

若没指定IPC_NOWAIT; msgsnd会阻塞,直到消息队列有空间为止

③msgrcv: 读取消息:

ssize_t msgrcv( int msgid, void* ptr, size_t nbytes, long type, int flag )

a. type == 0返回消息队列中第一个消息,先进先出

b. type >0

返回消息队列中类型为tpye的第一个消息

c. type <0

返回消息队列中类型 <=

|type| 的数据;若这种消息有若干个,则取类型值最小的消息

消息队列创建步骤:

#define

MSG_FILE "."

struct msgtype {

long mtype

char buffer[BUFFER+1]

}

if((key=ftok(MSG_FILE,'a'))==-1)

{

fprintf(stderr,"Creat Key Error:%s\n", strerror(errno))

exit

(1)

}

if((msgid=msgget(key, IPC_CREAT | 0666/*PERM*/))==-1)

{

fprintf(stderr,"Creat Message

Error:%s\n", strerror(errno))

exit

(1)

}

work queue是一种bottom half,中断处理的后半程,强调的是动态的概念,即work是重点,而queue是其次。

wait queue是一种「任务队列」,可以把一些进程放在上面睡眠等待某个事件,强调静态多一些,重点在queue上,即它就是一个queue,这个queue如何调度,什么时候调度并不重要

等待队列在内核中有很多用途,尤其适合用于中断处理,进程同步及定时。这里只说,进程经常必须等待某些事件的发生。例如,等待一个磁盘 *** 作的终止,等待释放系统资源,或者等待时间经过固定的间隔。

等待队列实现了在事件上的条件等待,希望等待特定事件的进程把放进合适的等待队列,并放弃控制权。因此。等待队列表示一组睡眠的进程,当某一条件为真时,由内核唤醒进程。

等待队列由循环链表实现,其元素包括指向进程描述符的指针。每个等待队列都有一个等待队列头,等待队列头是一个类型为wait_queue_head_t的数据结构。

等待队列链表的每个元素代表一个睡眠进程,该进程等待某一事件的发生,描述符地址存放在task字段中。然而,要唤醒等待队列中所有的进程有时并不方便。例如,如果两个或多个进程在等待互斥访问某一个要释放的资源,仅唤醒等待队列中一个才有意义。这个进程占有资源,而其他进程继续睡眠可以用DECLARE_WAIT_QUEUE_HEAD(name)宏定义一个新的等待队列,该宏静态地声明和初始化名为name的等待队列头变量。 init_waitqueue_head()函数用于初始化已动态分配的wait queue head变量等待队列可以通过DECLARE_WAITQUEUE()静态创建,也可以用init_waitqueue_head()动态创建。进程放入等待队列并设置成不可执行状态。

工作队列,workqueue,它允许内核代码来请求在将来某个时间调用一个函数。用来处理不是很紧急事件的回调方式处理方法.工作队列的作用就是把工作推后,交由一个内核线程去执行,更直接的说就是写了一个函数,而现在不想马上执行它,需要在将来某个时刻去执行,那就得用工作队列准没错。

如果需要用一个可以重新调度的实体来执行下半部处理,也应该使用工作队列。是唯一能在进程上下文运行的下半部实现的机制。这意味着在需要获得大量的内存时、在需要获取信号量时,在需要执行阻塞式的I/O *** 作时,都会非常有用。

创建一个per-CPU *编译期间静态创建一个per-CPUDEFINE_PER_CPU(type, name) 创建一个名为name,数据类型为type的per-CPU,比如static DEFINE_PER_CPU(struct sk_buff_head, bs_cpu_queues),此时每个CPU都有一个名叫bs_cpu_queues,数据结构为sk_buff_head的变量副本。每个副本都是在自己的CPU上工作。 * 动态创建per-CPU,以下代码是内核create_workqueue实现的片断 struct workqueue_struct *__create_workqueue(const char *name, int singlethread) { int cpu, destroy = 0struct workqueue_struct *wqstruct task_struct *p wq = kzalloc(sizeof(*wq), GFP_KERNEL)if (!wq) return NULL wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct)if (!wq->cpu_wq) { kfree(wq)return NULL } …… }


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8298430.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-15
下一篇 2023-04-15

发表评论

登录后才能评论

评论列表(0条)

保存