C语言多线程编程-线程间通信

发布时间:2024年01月04日

介绍

在C语言中,采用多线程编程,我们经常会遇到,线程之前需要同步数据,或者一个线程处理后的的数据,需要给另外一个线程进行处理,这就需要线程之间进行通讯,多线程间的通信和同步是通过操作系统提供的API实现的。下面是常见的线程间通信和同步机制:

  1. 互斥量(Mutexes):用于保护临界区,防止多个线程同时访问共享资源造成的数据不一致。POSIX线程库中的pthread_mutex_t类型可用于创建和管理互斥锁。

    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, NULL);
    pthread_mutex_lock(&mutex);  // 进入临界区前加锁
    // 访问共享资源的代码
    pthread_mutex_unlock(&mutex);  // 退出临界区后解锁
    
  2. 条件变量(Condition Variables):配合互斥量使用,允许一个线程等待特定条件发生后再继续执行。例如,当队列为空时,生产者线程等待消费者线程发出通知。

    pthread_cond_t cond;
    pthread_mutex_t mutex;
    pthread_cond_init(&cond, NULL);
    pthread_mutex_lock(&mutex);
    while (queue_is_empty()) { // 检查条件
        pthread_cond_wait(&cond, &mutex); // 条件不满足则等待
    }
    // 条件满足,处理数据
    pthread_mutex_unlock(&mutex);
    
  3. 信号量(Semaphores):是一种更通用的同步原语,可以用来控制对有限资源的访问数量。POSIX中有sem_t类型的信号量。

    sem_t semaphore;
    sem_init(&semaphore, 0, MAX_THREADS); // 初始化信号量,设置最大并发数
    sem_wait(&semaphore);  // 请求资源,若资源不足则阻塞
    // 使用资源
    sem_post(&semaphore);  // 释放资源
    
  4. 事件(Events or Binary Semaphores):在Windows API中,事件对象可以用来指示某个状态的发生,线程可以等待这个状态改变。

    HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); // 创建手动重置事件,初始状态为未触发
    WaitForSingleObject(event, INFINITE); // 等待事件被触发
    SetEvent(event);  // 触发事件
    ResetEvent(event);  // 重置事件状态
    
  5. 消息队列(Message Queues):虽然不是所有C语言环境都支持,但在某些系统如Windows下,线程可以通过消息队列进行通信。一个线程向队列发送消息,另一个线程从队列接收并处理这些消息。

    // Windows API 示例
    PostThreadMessage(threadId, WM_USER, wParam, lParam); // 向指定线程的消息队列发送消息
    MSG msg;
    GetMessage(&msg, NULL, 0, 0); // 接收消息
    
  6. 共享内存(Shared Memory):虽然不是直接的通信方式,但通过全局或共享内存区域,不同线程可以交换数据。需要注意的是,即使使用了共享内存,也必须结合上述同步原语来保证操作的原子性和一致性。

总结

每种方法都有其适用场景,在实际编程中,在保证线程通讯的同时,也要保证通讯数据的一致性。

文章来源:https://blog.csdn.net/scy518/article/details/135377126
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。