📜  多线程中的条件等待和信号(1)

📅  最后修改于: 2023-12-03 15:08:10.892000             🧑  作者: Mango

多线程中的条件等待和信号

简介

在多线程编程中,一个线程可能需要等待另一个线程完成某个任务后才能继续执行后续的操作,或者多个线程需要协作完成一个任务。这时就需要使用条件等待和信号的机制。

条件等待和信号是用于线程之间通信的一种机制。当一个线程等待某个条件时,它可以调用条件等待函数进入阻塞状态,直到另一个线程发出信号通知它继续执行。这样可以避免线程之间的忙等待,提高程序的效率。

条件等待

条件等待是指一个线程在等待某个条件成立时,进入阻塞状态。条件等待函数通常需要提供以下三个参数:

  • 一个条件变量,用于表示等待的条件。
  • 一个互斥锁,用于保护条件变量和共享资源。
  • 一个超时时间,用于设置等待的最长时间。

在等待期间,线程会解锁互斥锁,以便其他线程也能够访问共享资源。当条件成立时,等待的线程会被唤醒,并重新加锁互斥锁。

以下是一个简单的条件等待示例代码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pthread_mutex_t mutex;
pthread_cond_t cond;
int finished = 0;

void* thread_func(void* arg)
{
    printf("Thread %ld start.\n", pthread_self());
    pthread_mutex_lock(&mutex);
    while (!finished)
    {
        pthread_cond_wait(&cond, &mutex);
        printf("Thread %ld is woken up.\n", pthread_self());
    }
    printf("Thread %ld is finished.\n", pthread_self());
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main()
{
    pthread_t thread1, thread2;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    pthread_create(&thread1, NULL, thread_func, NULL);
    pthread_create(&thread2, NULL, thread_func, NULL);
    sleep(1);
    printf("Broadcasting...\n");
    pthread_mutex_lock(&mutex);
    finished = 1;
    pthread_cond_broadcast(&cond);
    pthread_mutex_unlock(&mutex);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

这个示例程序启动了两个线程,并在一秒钟后向它们广播一个信号,告诉它们可以继续执行。两个线程都会在条件等待函数中阻塞,等待被信号唤醒。当线程被唤醒后,它会再次检查条件是否成立,如果成立就继续执行后续操作,否则就再次进入等待状态。

信号

信号是用于线程之间通信的一种基本机制。当一个线程需要另一个线程执行某个操作时,它可以通过发送信号的方式通知另一个线程。

在多线程编程中,通常使用条件变量和互斥锁完成对共享资源的保护,条件变量用于等待条件的成立,互斥锁用于保护共享资源。发送信号的时候,需要对这两个对象进行操作,以确保多个线程之间的同步。

以下是一个简单的信号示例代码:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pthread_mutex_t mutex;
pthread_cond_t cond;
int signal_sent = 0;

void* thread_func(void* arg)
{
    printf("Thread %ld start.\n", pthread_self());
    pthread_mutex_lock(&mutex);
    while (!signal_sent)
    {
        pthread_cond_wait(&cond, &mutex);
    }
    signal_sent = 0;
    printf("Thread %ld received signal.\n", pthread_self());
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main()
{
    pthread_t thread1, thread2;
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);
    pthread_create(&thread1, NULL, thread_func, NULL);
    pthread_create(&thread2, NULL, thread_func, NULL);
    sleep(1);
    printf("Signalling...\n");
    pthread_mutex_lock(&mutex);
    signal_sent = 1;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

这个示例程序启动了两个线程,并在一秒钟后向它们发送一个信号。两个线程都会在条件等待函数中阻塞,等待信号的到来。当信号到来后,其中一个线程会重新获得锁,进而继续执行后续操作。