linux c多线程如何通信

Linux 中,C 多线程通信可通过共享全局变量、传递参数、条件变量、

Linux C编程中,多线程通信是实现并发程序功能的关键部分,以下是几种常见的多线程通信方法及其详细描述:

信号量(Semaphore)

信号量是一种用于线程同步的计数器,可以控制多个线程对共享资源的访问,它分为二进制信号量和计数信号量两种。

类型 说明 用途
二进制信号量 只有0和1两个状态,类似于互斥锁 主要用于互斥访问共享资源
计数信号量 可以取任意非负整数值 用于控制对多个相同资源的访问

使用方法:

  • 初始化:sem_init()
  • P操作(等待):sem_wait()
  • V操作(释放):sem_post()
  • 销毁:sem_destroy()

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem;
void *thread_func(void *arg) {
    sem_wait(&sem); // P操作
    printf("Thread %d is in critical section
", *(int *)arg);
    sleep(1); // 模拟临界区操作
    printf("Thread %d leaves critical section
", *(int *)arg);
    sem_post(&sem); // V操作
    return NULL;
}
int main() {
    pthread_t threads[5];
    int thread_ids[5];
    sem_init(&sem, 0, 1); // 初始化二进制信号量为1
    for (int i = 0; i < 5; i++) {
        thread_ids[i] = i;
        pthread_create(&threads[i], NULL, thread_func, &thread_ids[i]);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }
    sem_destroy(&sem); // 销毁信号量
    return 0;
}

互斥锁(Mutex)与条件变量(Condition Variable)

互斥锁用于保护共享资源,确保同一时刻只有一个线程可以访问该资源,条件变量则用于线程间的等待和通知机制。

使用方法:

  • 初始化互斥锁:pthread_mutex_init()
  • 加锁:pthread_mutex_lock()
  • 解锁:pthread_mutex_unlock()
  • 销毁互斥锁:pthread_mutex_destroy()
  • 初始化条件变量:pthread_cond_init()
  • 等待条件变量:pthread_cond_wait()
  • 发出条件变量信号:pthread_cond_signal()pthread_cond_broadcast()
  • 销毁条件变量:pthread_cond_destroy()

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t mutex;
pthread_cond_t cond;
int count = 0;
void *producer(void *arg) {
    pthread_mutex_lock(&mutex);
    count++;
    printf("Producer: %d
", count);
    pthread_cond_signal(&cond); // 通知消费者
    pthread_mutex_unlock(&mutex);
    return NULL;
}
void *consumer(void *arg) {
    pthread_mutex_lock(&mutex);
    while (count == 0) { // 如果计数为0,等待条件变量
        pthread_cond_wait(&cond, &mutex);
    }
    printf("Consumer: %d
", count);
    count--;
    pthread_mutex_unlock(&mutex);
    return NULL;
}
int main() {
    pthread_t prod, cons;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    pthread_create(&prod, NULL, producer, NULL);
    pthread_create(&cons, NULL, consumer, NULL);
    pthread_join(prod, NULL);
    pthread_join(cons, NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

消息队列(Message Queue)

消息队列允许线程之间通过发送和接收消息来进行通信,每个消息都包含一个优先级,系统会根据优先级将消息排序。

使用方法:

  • 创建消息队列:msgget()
  • 发送消息:msgsnd()
  • 接收消息:msgrcv()
  • 删除消息队列:msgctl()

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf {
    long mtype;
    char mtext[100];
};
int main() {
    key_t key = ftok("progfile", 65);
    int msgid = msgget(key, 0666 | IPC_CREAT);
    struct msgbuf message;
    // 发送消息
    message.mtype = 1;
    strcpy(message.mtext, "Hello World");
    msgsnd(msgid, &message, sizeof(message), 0);
    printf("Message sent: %s
", message.mtext);
    // 接收消息
    msgrcv(msgid, &message, sizeof(message), 0, 0);
    printf("Message received: %s
", message.mtext);
    // 删除消息队列
    msgctl(msgid, IPC_RMID, NULL);
    return 0;
}

管道(Pipe)和命名管道(FIFO)

管道是一种单向通信机制,数据只能在一个方向上流动,命名管道(FIFO)则可以用于不相关的进程间通信。

使用方法:

  • 创建管道:pipe()(匿名管道)或mkfifo()(命名管道)
  • 读写管道:使用read()write()函数进行数据传输
  • 关闭管道:close()

示例代码(匿名管道):

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
int pipefd[2];
void *writer(void *arg) {
    char buffer[] = "Hello from writer";
    write(pipefd[1], buffer, strlen(buffer)+1); // 写入管道
    return NULL;
}
void *reader(void *arg) {
    char buffer[100];
    read(pipefd[0], buffer, sizeof(buffer)); // 从管道读取数据
    printf("Reader received: %s
", buffer);
    return NULL;
}
int main() {
    pipe(pipefd); // 创建匿名管道
    pthread_t wtid, rtid;
    pthread_create(&wtid, NULL, writer, NULL);
    pthread_create(&rtid, NULL, reader, NULL);
    pthread_join(wtid, NULL);
    pthread_join(rtid, NULL);
    close(pipefd[0]); // 关闭读端
    close(pipefd[1]); // 关闭写端
    return 0;
}

共享内存(Shared Memory)

共享内存是最快的进程间通信方式之一,多个线程可以直接读写同一块内存区域,通常与信号量结合使用,以实现同步。

使用方法:

  • 创建共享内存段:shmget()
  • 附加到进程地址空间:shmat()
  • 分离共享内存段:shmdt()
  • 删除共享内存段:shmctl()

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
int main() {
    key_t key = ftok("shmfile",69); // 生成IPC键值
    int shmid = shmget(key,1024,0666|IPC_CREAT); // 创建共享内存段
    char *str = (char*) shmat(shmid,(void*)0,0); // 附加到进程地址空间
    printf("Write Data: ");
    fgets(str,1024,stdin); // 从标准输入读取数据到共享内存中
    printf("Data written in memory: %s
",str); // 显示写入的数据内容
    shmdt(str); // 分离共享内存段以防止未预期修改导致错误结果发生风险增加安全性考虑因素之一就是及时正确地释放资源避免资源泄露等问题产生负面影响甚至崩溃程序运行环境稳定性可靠性降低用户体验满意度下降等不良后果发生概率增大因此必须重视资源管理问题并采取相应措施加以解决才能保证软件产品质量达到较高水平满足用户需求期望值提升市场竞争力促进企业发展壮大进步!(此处仅为示例实际开发中应更加谨慎处理资源释放问题)
    return 0;
}

小伙伴们,上文介绍linux c多线程如何通信的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。

原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/12093.html

(0)
酷番叔酷番叔
上一篇 2025年8月18日 08:42
下一篇 2025年8月18日 08:47

相关推荐

  • linux t进程如何处理

    nux 中终止进程可通过 kill 命令,后跟进程 ID,也可使用 `kill

    2025年8月18日
    10400
  • 如何移植Linux内核?

    移植Linux内核是一个涉及硬件适配、软件配置和系统调试的复杂过程,主要针对嵌入式设备或特定硬件平台,以下从环境准备、内核配置、编译优化、烧录调试等环节详细说明操作步骤和注意事项,移植前的环境准备移植内核前需搭建完整的开发环境,确保工具链和硬件支持到位,交叉编译工具链:根据目标板架构(如ARM、ARM64、RI……

    2025年8月30日
    9000
  • 如何检查Linux网卡状态?

    在虚拟机中运行Linux系统时,网络连接是基础需求,以下是详细配置指南,涵盖主流虚拟机软件(VirtualBox/VMware)和Linux系统(以Ubuntu为例),遵循E-A-T原则(专业性、权威性、可信度),确保内容准确可靠:虚拟机网络模式解析(关键基础)NAT模式(推荐新手)原理:虚拟机共享主机IP,通……

    2025年7月15日
    10200
  • 哪些命令行工具能提升效率?

    在Linux系统中,查看磁盘分区是系统管理、磁盘空间监控和故障排查的基础操作,以下详细介绍多种可靠方法,涵盖命令行工具和图形界面方案,所有步骤均经过验证并遵循Linux最佳实践,操作前请确保您有普通用户权限,部分命令需sudo提升权限(谨慎操作),lsblk(最直观)作用:列出所有块设备(磁盘、分区)的树状结构……

    2025年7月21日
    12300
  • Linux系统下Wireshark怎么用?新手详细操作步骤与使用技巧

    在Linux系统中使用Wireshark进行网络流量分析,需要完成安装、启动、捕获、过滤及分析等步骤,以下是详细操作指南,安装Wireshark不同Linux发行版的安装命令略有差异:Ubuntu/Debian:执行sudo apt update && sudo apt install wire……

    2025年8月29日
    11000

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN

关注微信