📜  操作系统信号量介绍(1)

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

操作系统信号量介绍

操作系统信号量是一种同步工具,它能够协调多个线程之间的操作,从而避免资源竞争和死锁。本文将介绍操作系统信号量的基本概念和用法。

信号量的基本概念

操作系统信号量是一个计数器,用于记录可以访问共享资源的线程数量。当一个线程想要访问共享资源时,它需要获取一个信号量。如果线程成功获取了信号量,它就可以访问共享资源。当线程访问完毕后,它必须释放信号量,以便其他线程可以访问共享资源。

信号量有两种类型:二元信号量和计数信号量。二元信号量只能有两个取值:0和1。计数信号量可以有任意的正整数作为取值。

信号量的用法

在C语言中,操作系统提供了一组用于操作信号量的函数。下面是这些函数的原型:

#include <semaphore.h>

int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_post(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
  • sem_init:用于创建一个新的信号量。参数sem为指向信号量的指针,pshared为0时代表信号量只能用于同一进程中的不同线程之间的同步,为非0时代表信号量可以用于不同进程之间的同步。value为信号量的初值。
  • sem_destroy:用于销毁一个信号量。
  • sem_post:用于释放一个信号量。
  • sem_wait:用于获取一个信号量,如果当前信号量的值为0,则等待直到有一个线程释放信号量。
  • sem_trywait:与sem_wait类似,但它只是尝试获取一个信号量,如果当前信号量的值为0,则它不会等待而是立即返回一个错误。
信号量实例

下面是一个使用信号量进行线程同步的实例:

#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>

#define THREAD_NUM 5

sem_t sem;

void *thread_func(void *arg)
{
    int id = *(int *)arg;
    printf("Thread %d starts.\n", id);
    sem_wait(&sem);
    printf("Thread %d gets the semaphore.\n", id);
    // Access the shared resource.
    sem_post(&sem);
    printf("Thread %d releases the semaphore.\n", id);
    return NULL;
}

int main()
{
    pthread_t threads[THREAD_NUM];
    sem_init(&sem, 0, 1); // Initialize the semaphore with the value 1.
    int i;
    for (i = 0; i < THREAD_NUM; i++)
    {
        int *id = malloc(sizeof(int));
        *id = i;
        pthread_create(&threads[i], NULL, thread_func, id);
    }
    for (i = 0; i < THREAD_NUM; i++)
    {
        pthread_join(threads[i], NULL);
    }
    sem_destroy(&sem);
    return 0;
}

在上面的实例中,我们创建了5个线程,并用信号量控制它们对共享资源的访问。在每个线程中,它们都需要获取信号量才能访问共享资源。如果当前信号量的值为0,则线程将等待直到有一个线程释放信号量。当线程访问完共享资源后,它必须释放信号量,以便其他线程可以访问共享资源。

总结

操作系统信号量是一种强大的同步工具,它可以协调多个线程之间的操作,从而避免资源竞争和死锁。通过使用操作系统提供的信号量函数,我们可以轻松地实现线程同步。