掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务

C语言线程间通信的几种方法(两个线程如何通信)

在C语言中,线程间通信是一个复杂而重要的主题。多线程编程允许程序同时执行多个任务,但同时也带来了数据共享和同步的挑战。本文将详细介绍如何在C语言中实现线程间的通信,包括互斥锁、条件变量、信号量、消息队列和管道等方法

一、互斥锁(Mutex)

互斥锁是一种常用的线程同步机制,它用于保护共享资源的访问。互斥锁通过在关键代码段前后加锁和解锁操作,确保在同一时间只有一个线程可以访问共享资源。其他线程则必须等待当前线程释放锁后才能继续执行。

 i < NUM_THREADS; i++) {
        pthread_create(&threads[i], NULL, increment_counter, NULL);
    }
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    pthread_mutex_destroy(&mutex);
    return 0;
}

在这个例子中,pthread_mutex_lock和pthread_mutex_unlock函数用于保护counter变量,确保每次只有一个线程可以修改它。

二、条件变量(Condition Variable)

条件变量是一种用于线程间通信的同步机制,当某个条件满足时,它可以唤醒等待的线程。条件变量通常与互斥锁一起使用,通过阻塞和唤醒操作来实现线程间的协调。

#include 
#include 
#include 
#define NUM_THREADS 5
pthread_mutex_t mutex;
pthread_cond_t cond;
int ready = 0;
int data = 0;ready) {
        pthread_cond_wait(&cond, &mutex);
    }
    printf("Data: %d
", data); // Produce data
    ready = 1; // Notify the condition has changed
    pthread_cond_signal(&cond); // Signal to consumer thread
    pthread_mutex_unlock(&mutex);
    return NULL;
}
int main() {
    pthread_t threads[NUM_THREADS];
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    pthread_create(&threads[0], NULL, consumer, NULL);
    pthread_create(&threads[1], NULL, producer, NULL);
    pthread_join(threads[0], NULL);
    pthread_join(threads[1], NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

在这个示例中,生产者线程生成数据并通知消费者线程,消费者线程等待数据准备好后再进行处理。

三、信号量(Semaphore)

信号量是一种用于控制多个线程对共享资源访问的同步机制。它通过计数器来限制同时访问资源的线程数量。当信号量的值大于0时,线程可以继续访问共享资源;当信号量的值等于0时,线程会被阻塞。

#include 
#include 
#include 
#include 
#define NUM_THREADS 5
sem_t sem;
int counter = 0; // Decrement the semaphore
    counter++;
    printf("Counter value: %d
", counter);
    sem_post(&sem); // Increment the semaphore
    return NULL;
}
int main() {
    pthread_t threads[NUM_THREADS];
    sem_init(&sem, 0, 3); // Initialize semaphore with 3 slots
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_create(&threads[i], NULL, increment_counter, NULL);
    }
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    sem_destroy(&sem); // Clean up semaphore
    return 0;
}

在这个例子中,sem_wait和sem_post函数用于控制对共享资源的访问。

四、消息队列(Message Queue)

消息队列是一种在多线程环境下进行线程间通信的机制。不同的线程可以通过向消息队列发送消息和从消息队列接收消息来进行通信。消息队列可以实现线程之间的异步通信,提高系统的响应速度和并发性能。

#include <sys ipc.msg_text, max_text, stdin); =""  send message to queue    printf("Data sent is: %s
", msg. // Receive message from queue
    printf("Data received is: %s
", msg. // Clean up message queue
    return 0;
}

在这个示例中,msgsnd和msgrcv函数用于发送和接收消息。消息队列提供了一种高效且安全的线程间通信方式。

五、管道(Pipe)

管道是一种常用的线程间通信机制,可以用于在父子进程或兄弟进程之间进行通信。在多线程环境下,可以使用管道来实现线程之间的通信。一个线程可以通过管道的写端向管道发送数据,另一个线程可以通过管道的读端从管道接收数据。通过管道的读写操作,可以实现线程之间的数据交换。

#include <unistd.   create a pipe    const char *data = "Hello from producer";
    write(pipefd[1], data, strlen(data) + 1); // Write data to pipe
    close(pipefd[1]); // Create a pipe (the same one as in producer)
    char buffer[100];
    read(pipefd[0], buffer, sizeof(buffer)); // Read data from pipe
    printf("Consumer received: %s
", buffer);
    close(pipefd[0]); // Close the read end of the pipe
    return NULL;
}
int main() {
    pthread_t t1, t2;
    pthread_create(&t1, NULL, producer, NULL); // Create producer thread
    pthread_create(&t2, NULL, consumer, NULL); // Create consumer thread
    pthread_join(t1, NULL); // Wait for producer to finish
    pthread_join(t2, NULL); // Wait for consumer to finish
    return 0;
}

在这个示例中,生产者线程向管道写入数据,消费者线程从管道读取数据,实现了线程间的通信。

C语言提供了多种线程间通信的方法,每种方法都有其适用的场景和特点。开发者应根据具体需求选择合适的通信方式,以确保线程间的数据一致性和系统的稳定性。

声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

  • 全球天气预报

    支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等

    支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等

  • 购物小票识别

    支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景

    支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景

  • 涉农贷款地址识别

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

    涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。

  • 人脸四要素

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

    根据给定的手机号、姓名、身份证、人像图片核验是否一致

  • 个人/企业涉诉查询

    通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。

    通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。

0512-88869195
数 据 驱 动 未 来
Data Drives The Future