首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux 线程间 队列通讯

Linux线程间队列通讯基础概念

在Linux系统中,线程间通信(Inter-thread Communication, ITC)是一种机制,允许不同的线程共享数据和信息。队列通讯是其中一种常见的方法,主要用于在生产者和消费者线程之间传递数据。

基础概念

  1. 队列(Queue):一种先进先出(FIFO)的数据结构,用于存储和管理数据元素。
  2. 生产者线程(Producer Thread):负责生成数据并将其放入队列中。
  3. 消费者线程(Consumer Thread):负责从队列中取出数据并进行处理。

相关优势

  1. 解耦:生产者和消费者线程通过队列进行通信,彼此之间不需要直接依赖,降低了耦合度。
  2. 缓冲:队列可以作为缓冲区,平衡生产者和消费者之间的速度差异。
  3. 并发控制:通过队列可以有效地管理线程间的同步和互斥问题。

类型

  1. 有界队列:队列有一个固定的大小限制,当队列满时,生产者线程会被阻塞。
  2. 无界队列:队列大小不受限制,但需要注意内存消耗。

应用场景

  1. 任务分发:多个生产者线程生成任务,一个或多个消费者线程处理任务。
  2. 日志处理:多个线程生成日志,一个专门的线程负责写入日志文件。
  3. 数据流水线:多个阶段的数据处理,每个阶段由不同的线程完成。

示例代码

以下是一个简单的C语言示例,展示了如何使用POSIX线程(pthread)和队列进行线程间通信。

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#define QUEUE_SIZE 10
#define MAX_ITEM 100

typedef struct {
    int buffer[QUEUE_SIZE];
    int front;
    int rear;
    int count;
    pthread_mutex_t lock;
    pthread_cond_t not_empty;
    pthread_cond_t not_full;
} Queue;

Queue queue;

void* producer(void* arg) {
    for (int i = 0; i < MAX_ITEM; ++i) {
        pthread_mutex_lock(&queue.lock);
        while (queue.count == QUEUE_SIZE) {
            pthread_cond_wait(&queue.not_full, &queue.lock);
        }
        queue.buffer[queue.rear] = i;
        queue.rear = (queue.rear + 1) % QUEUE_SIZE;
        queue.count++;
        pthread_cond_signal(&queue.not_empty);
        pthread_mutex_unlock(&queue.lock);
        usleep(100);
    }
    return NULL;
}

void* consumer(void* arg) {
    for (int i = 0; i < MAX_ITEM; ++i) {
        pthread_mutex_lock(&queue.lock);
        while (queue.count == 0) {
            pthread_cond_wait(&queue.not_empty, &queue.lock);
        }
        int item = queue.buffer[queue.front];
        queue.front = (queue.front + 1) % QUEUE_SIZE;
        queue.count--;
        pthread_cond_signal(&queue.not_full);
        pthread_mutex_unlock(&queue.lock);
        printf("Consumed: %d\n", item);
        usleep(200);
    }
    return NULL;
}

int main() {
    pthread_t producer_thread, consumer_thread;

    pthread_mutex_init(&queue.lock, NULL);
    pthread_cond_init(&queue.not_empty, NULL);
    pthread_cond_init(&queue.not_full, NULL);

    queue.front = queue.rear = queue.count = 0;

    pthread_create(&producer_thread, NULL, producer, NULL);
    pthread_create(&consumer_thread, NULL, consumer, NULL);

    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);

    pthread_mutex_destroy(&queue.lock);
    pthread_cond_destroy(&queue.not_empty);
    pthread_cond_destroy(&queue.not_full);

    return 0;
}

可能遇到的问题及解决方法

  1. 死锁:当线程在等待某个条件时,可能会导致死锁。解决方法包括确保所有线程按照相同的顺序获取锁,以及使用超时机制。
  2. 竞态条件:多个线程同时访问共享资源可能导致数据不一致。使用互斥锁(mutex)和条件变量(condition variable)可以有效避免竞态条件。
  3. 内存泄漏:未正确释放动态分配的内存会导致内存泄漏。确保在适当的时候释放内存,并使用工具进行内存泄漏检测。

通过上述方法和示例代码,可以有效地实现Linux线程间的队列通讯,并解决常见的并发问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

iOS--多线程之线程间通讯

线程间通讯 一、NSThread 1.简单说明 ①线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 ②线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后...,转到另1个线程继续执行任务 ③线程间通信常用方法 // waitUntilDone的含义: // 如果传入的是YES: 那么会等到主线程中的方法执行完毕, 才会继续执行下面其他行的代码 //...@"花费了多少秒 %f", [end timeIntervalSinceDate:begin]); 二、GCD 案例,下载图片,然后在屏幕上显示 在dispatch_get_main_queue() 队列中...// 一般情况下, 在做企业开发时候, 都会定义一个全局的自定义队列, 便于使用 NSOperationQueue *queue = [[NSOperationQueue alloc]...]; }]; // 6.添加依赖 [op3 addDependency:op1]; [op3 addDependency:op2]; // 7.添加操作到队列中

99680

线程间通讯:WaitHandler使用实例及分析

实例效果: 1.点击“启动线程”会启动一个线程t每隔2秒在listbox上插入一条新记录。 2.点击“关闭线程”会停止线程t,但不是马上停止而是等待线程t当次循环的工作后再结束。...上述代码中线程t自杀时通过另一个ManualResetEvent实例告诉ui线程“我挂了!”,好让ui线程做善后工作。...检查线程t是否已死的过程是一直占用ui线程的,而窗口上控件的交互也是由ui线程来处理,这时会出现画面假死的状态,如果发出了调用ui线程处理其他事件的话就会有异常。...这时加上一句Application.DoEvents()表示让处理当前消息队列中的所有window消息,就是说ui线程抽出一部分时间来处理消息队列中的其他消息(如界面的交互),而不是完成了第一个消息再着手后面的消息...注意:这时ui线程是可用的,只是正忙于处理第一个消息,如果ui线程挂起来了、阻塞了或死了Application.DoEvents()无法使让ui线程处理消息队列中的其他消息。

63650
  • Linux进程间通信 消息队列

    消息队列 是消息的链接表,存储内核中,由消息标识符标识。 --《UNIX环境高级编程》 简单理解,消息队列就是一堆消息的有序集合,并缓存于内核中。...,其中cmd指进行的操作,buf记录了消息队列的信息。...总结 消息队列在进程间通信的优势总结起来有以下几点: 缓存:数据较大的消息处理起来时间较长,此时将其写入消息队列更快,待系统空闲时再处理。提高系统任务执行效率。...送达:消息队列存储的消息,会一直保留在队列中直到消息被处理,且被取走后就会被队列释放。因此无论多少个进程在获取,每个消息仅会被处理一次。 排序:消息在队列中一直按照“先入先出”的顺序来执行。...异步:消息队列因为会缓存消息,且顺序处理不会丢失。因此多个进程可通过消息队列实现异步通信,互不阻塞。

    4.6K40

    Linux进程间通信——消息队列(一)

    今天就聊一聊Linux系统进程之间的通信。...程序环境:ubuntu16.04 x_64 虚拟机 一、站得高,望得远 有三种IPC(进程间通讯)我们称作XSI IPC,即消息队列、信号量和共享内存 1....POSIX的超集 ③X/Open System Interface(XSI IPC) 符合Single UNIX规范的系统的核心应用程序编程接口 有点儿蒙圈吧,正常正常~ 个人理解:听说过POSIX多线程程序设计吧...,就是符合①的可移植操作系统接口的多线程设计,然后②又是①的超集,再然后③是符合②的......可能很多人就是因为这些才不想学一些东西吧,不过这些不清楚也没多大关系 2....进程间通信根据是否在同一台主机上进行通信可分为无名管道和有名管道(FIFO),消息队列、信号量和共享内存这些都是只能在同一台主机上进行通信的 Socket和Streams(这个没接触过)是可以在不同主机上进行进程通讯的

    3K20

    Linux进程间通信(二) - 消息队列

    消息队列 消息队列是Linux IPC中很常用的一种通信方式,它通常用来在不同进程间发送特定格式的消息数据。...消息队列是随内核的持续性,即一个进程向消息队列写入消息后,然后终止,另外一个进程可以在以后某个时刻打开该队列读取消息。只要内核没有重新自举,消息队列没有被删除。...消息队列中的每条消息通常具有以下属性: Ø 一个表示优先级的整数; Ø 消息的数据部分的长度; Ø 消息数据本身; 下面我们分别阐述POSIX消息队列和System V消息队列,这2种消息队列目前Linux...在Linux 2.6中该类型的定义为整型: #include typedef int mqd_t; // 关闭消息队列 mqd_t mq_close(mqd_t mqdes...下面是在Linux 2.6下shell对启动进程的POSIX消息队列大小的限制: [root@rocket ipc]# ulimit -a|grep message POSIX message queues

    6.2K90

    Linux进程间通信之消息队列

    一,消息队列 1,概念:“消息队列”是在消息的传输过程中保存消息的容器 2,消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。   ...对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息;   对消息队列有读权限的进程则可以从消息队列中读走消息。   消息队列是随内核持续的。...3,编程注意事项:使用时先把数据封装成消息,把消息存入队列 编程步骤: 具体函数的用法可以用man手册查看(强力推荐) (1)ftok()生产key (2)使用msgget( ) 创建/获取消息队列,返回值是队列标识符...(3)使用msgsnd( ) 发送消息     使用msgrcv( ) 接收消息 (4)使用msgctl( ) 删除消息队列 4,实例: sendmsg.c   用来发送消息的 // sendmsg.c...msg2.buf, "hello, msg1"); msgsnd(msgid, &msg2, sizeof(msg2), 0); // 阻塞 printf("消息发送完成,按回车销毁消息队列

    2.9K90

    Linux 线程间通信和同步

    如果 CPU 是单核,同一时间只有一个进程在执行,多核 CPU 可以同一时间点有多个进程在执行。...优缺点: 一个进程死了不影响其他进程,一个线程崩溃很可能影响到它本身所处的整个进程。 创建多进程的系统花销大于创建多线程。 多进程通讯因为需要跨越进程边界,不适合大量数据的传送。...多线程无需跨越进程边界,适合大量数据的传送。 3、什么时候用进程,什么时候用线程 创建和销毁较频繁使用线程,因为创建进程花销大。 需要大量数据传送使用线程,因为多线程切换速度快,不需要跨越进程边界。...安全稳定选进程;快速频繁选线程; 二、线程间通信/同步 上一篇文章我们讲了进程间通信的六种方式:管道和 FIFO、信号、消息队列、信号量、共享内存、套接字(Socket),今天我们讲一下线程间通信/同步的方式...线程同步的方法:互斥锁、条件变量、自旋锁、读写锁,除此之外,还有信号量、屏障等等,在 Linux 应用开发当中,用的最多的还是互斥锁和条件变量。 为什么需要线程同步?

    1.6K10

    Linux基础(进线程间的竞争)

    3,当线程的调度策略为SCHED_RR时,情况跟SCHED_FIFO是一样的,区别在于:每一个SHCED_RR策略下的线程都将会被分配一个额度的时间片,当时间片耗光时,他会被放入其所在优先级队列的队尾的位置...4,当线程的调度策略为SCHED_OTHER时,其静态优先级必须设置为0(即普通线程)。该调度策略是Linux系统调度的默认策略。...100个静态优先级,对应内核任务管理中的100条队列,好比银行排队等到办理业务的100个窗口,每一条队列都站着一些等到调度的线程。...其中第0号队列全是屌丝(即所谓的普通线程),第1-99号队列都是VIP,而且数字越大优先级越高。...银行里服务柜员相当于CPU,是一个极快动作的业务员,迅速地在各个窗口间轮流切换,当然,她会优先处理高优先级的客户,比如优先级为90的客户是存款500万以上的VIP,一般他的事务紧急不容怠慢。 ? ?

    76440

    Linux系统编程-进程间通信(消息队列)

    前面文章介绍了Linux下进程的创建,管理,陆续介绍了进程间通信的方式:管道、内存映射、共享内存等。这篇文章继续介绍Linux的进程间通信方式消息队列。 1....消息队列介绍 消息队列通过名字字面意思理解就是队列排队-和平常超市买东西排队付款一样结构,消息队列与FIFO很相似,都是一个队列结构,都可以有多个进程往队列里面写信息,多个进程从队列中读取信息。...而消息队列可以事先往队列中写信息,需要时再打开读取信息。 注意事项: 消息队列属于顺序队列形式的结构,向队列里写的每一条消息,会追加到队列后面,读取一个就从队列里消除一个。...msgget要么返回新创建的消息队列id,要么返回具有相同key值的消息队列id;如果IPC_EXCL和IPC_CREAT同时指明,则要么创建新的消息队列,要么当队列存在时,调用失败并返回-1。...案例代码: 消息队列基本使用 下面两个例子,一个例子用于创建队列,并向队列里写数据,另一个例子从队列里读取数据。 4.1 向队列写入消息 程序运行需要传入两个额外的参数。

    1.9K40

    Linux系统编程——进程间通信:消息队列

    消息队列允许一个或多个进程向它写入或者读取消息。 与无名管道、命名管道一样,从消息队列中读出消息,消息队列中对应的数据都会被删除。...每个消息队列都有消息队列标识符,消息队列的标识符在整个系统中是唯一的。 消息队列是消息的链表,存放在内存中,由内核维护。只有内核重启或人工删除消息队列时,该消息队列才会被删除。...若不人工删除消息队列,消息队列会一直存在于系统中。...不能当面直接给 B,这时候他们需要借助第三方托管(如银行),A 找到某个具体地址的建设银行,然后把东西放到某个保险柜里(如 1 号保险柜),对于 B 而言,要想成功取出 A 的东西,必须保证去同一地址的同一间银行取东西...键(key)值 System V 提供的进程间通信机制需要一个 key 值,通过 key 值就可在系统内获得一个唯一的消息队列标识符。key 值可以是人为指定的,也可以通过 ftok() 函数获得。

    1.4K10

    Linux进程间通信【消息队列、信号量】

    ,扩展 IPC 的知识栈,尤其是 信号量,可以通过它,为以后多线程学习中 POSIX 信号量的学习做铺垫 ---- ️正文 1、消息队列 1.1、什么是消息队列?...shmget 可以说是十分相似了,关于 ftok 函数计算 key 值,这里就不再阐述,可以在这篇文章中学习 《Linux进程间通信【共享内存】》 简单使用函数 msgget 创建 消息队列,并使用...同时应用也更为广泛 因为 信号量 需要被多个独立进程看到,所以 信号量 本身也是 临界资源,不过它是 原子 的,所以可以用于 互斥 多个独立进程看到同一份资源,这就是 IPC 的目标,所以 信号量 被划分至进程间通信中...假设想访问具体 ipc 中的资源,可以通过 ipc_id_arr[n] 强转为对应类型指针,再通过 -> 访问其中的其他资源 以上方法就是 多态,通过父类指针,访问成员 ---- 总结 以上就是本次关于 Linux...进程间通信【消息队列、信号量】的全部内容了,消息队列和信号量相对来说不怎么重要,因此本文主要以理论为主,并未涉及很多实操代码;本文中最重要的内容莫过于理解 互斥 相关概念与 信号量 实现互斥的原理,最后关于操作系统对

    61730

    【Linux】线程间同步实践 —— 生产消费模型

    就比如:学校有一个vip自习室(1人间),门口存放着钥匙,来到自习室的人可以拿着钥匙进入自习室,并带走钥匙,离开时将钥匙放回原处。...这样的场景就是仅仅凭借一把锁是不能保证线程运行的顺序性的,所以要进行同步。也就是保证所有人访问自习室,未来是安全的并且还有一定顺序性。线程也是如此!通过条件变量我们可以进行线程间的同步!...生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力...其与普通的队列区别在于,当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中被放入了元素;当队列满时,往队列里存放元素的操作也会被阻塞,直到有元素被从队列中取出(以上的操作都是基于不同的线程来说的,...线程在对阻塞队列进程操作时会被阻塞) 3.1 框架搭建 阻塞队列的本质还是队列,所以底层需要一个队列来储存数据(使用模版来适配各种类型数据)。

    13710

    C# 进程间通讯

    一、进程间通讯的方式 1)共享内存 包括:内存映射文件,共享内存DLL,剪切板。 2)命名管道及匿名管道 3)消息通讯 4)利用代理方法。例如SOCKET,配置文件,注册表方式。 等方式。...方法一:通讯。...进程间通讯的方式有很多,常用的有共享内存(内存映射文件、共享内存DLL、剪切板等)、命名管道和匿名管道、发送消息等几种方法来直接完成,另外还可以通过socket口、配置文件和注册表等来间接实现进程间数据通讯任务...二、发送消息实现进程间通讯前准备 下面的例子用到一个windows api 32函数 [DllImport("User32.dll", EntryPoint = "SendMessage")] private...三、发送消息实现进程间通讯具体步骤 1.新建windows应用程序 (1)打开VS2008,新建一个“windows 应用程序”,主窗口为Form1,项目名称:ProcessCommunication

    1.5K20

    进程间通讯(一).pipe

    前言 UNIX/Linux 是多任务的操作系统,通过多个进程分别处理不同事务来实现,如果多个进程要进行协同工作或者争用同一个资源时,互相之间的通讯就很有必要了 进程间通信,Inter process...) 消息队列 ( message queues ) 共享内存 ( shared memory ) 套接字 ( socket ) 这里分享一下我在学习进程通讯过程中的笔记和心得 ---- 概要 ----...消息队列( message queue ) : 消息队列是消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。...因此,主要作为进程间以及同一进程内不同线程之间的同步手段。...套接字( socket ) : 套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同主机间的进程通信。

    72630

    c语言线程间传递消息,线程间通信

    线程间通信 前面一章讲了线程间同步,提到了信号量、互斥量、事件集等概念;本章接着上一章的内容,讲解线程间通信。...RT-Thread 中则提供了更多的工具帮助在不同的线程中间传递信息,本章会详细介绍这些工具。学习完本章,大家将学会如何将邮箱、消息队列、信号用于线程间的通信。...rt_uint32_t*)&msg_ptr) == RT_EOK) { /* 在接收线程处理完毕后,需要释放相应的内存块 */ rt_free(msg_ptr); } 消息队列 消息队列是另一种常用的线程间通讯方式...可以应用在多种场合:线程间的消息交换、使用串口接收不定长数据等。 消息队列的工作机制 消息队列能够接收来自线程或中断服务例程中不固定长度的消息,并把消息缓存在自己的内存空间中。...消息队列的使用场合 消息队列可以应用于发送不定长消息的场合,包括线程与线程间的消息交换,以及中断服务例程中给线程发送消息(中断服务例程不能接收消息)。

    2.5K30
    领券