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)
酷番叔酷番叔
上一篇 2小时前
下一篇 2小时前

相关推荐

  • 如何将整个磁盘备份为镜像文件到移动硬盘?

    为什么需要系统备份?数据安全:防止硬件故障、误操作或病毒导致的数据丢失,系统迁移:快速将系统复制到新硬盘或新设备,灾难恢复:系统崩溃后10分钟内还原到正常状态,测试环境:备份后可安全测试新软件或配置,随时回滚,推荐工具及选择建议Clonezilla(首选工具)优点:支持全盘/分区备份、增量备份、跨平台(EXT4……

    2025年8月7日
    800
  • Linux目录权限如何保障系统安全?

    权限基础概念Linux目录权限分为三类:读(r):允许查看目录内容(如ls命令)写(w):允许创建/删除目录内文件执行(x):允许进入目录(如cd命令)权限分配对象:所有者(owner):目录创建者所属组(group):共享权限的用户组其他用户(others):系统所有其他用户修改权限的核心命令:chmod方法……

    2025年7月10日
    2300
  • 如何在Linux6系统中高效使用vi编辑器?

    进入vi编辑器的基本方法通过终端打开新文件打开终端(Terminal),输入以下命令创建或编辑文件:vi 文件名示例:vi myfile.txt若文件不存在,vi会自动创建;若存在,则打开现有文件,打开文件并跳转到指定行需编辑文件特定位置时(如调试脚本):vi +行号 文件名示例:vi +10 /etc/htt……

    2025年7月21日
    1300
  • linux如何识别u

    Linux中,可通过lsblk查看磁盘信息识别U盘,或用`f

    4天前
    500
  • 如何编译两个C文件生成可执行文件?

    在Linux系统中,Makefile是自动化编译的核心工具,尤其适用于管理多文件项目,它通过定义依赖关系和构建规则,显著提升开发效率,以下是详细指南:Makefile基础结构一个Makefile由规则组成,每条规则包含三个部分:目标(target): 依赖(dependencies) 命令(commands……

    2025年6月20日
    3200

发表回复

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

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN

关注微信