← 返回首页
Linux高级程序设计(八十一)
发表时间:2021-12-29 23:26:51
信号量的操作

1.信号量的初始化

sem_init函数实现创建一个信号量并初始化它的值。一个无名信号量在被使用前必须先初始化。

#include <semaphore.h> 
int sem_init(sem_t *sem, int pshared, unsigned int value);

参数: - sem:信号量的地址。 - pshared:等于 0,信号量在线程间共享(常用);不等于0,信号量在进程间共享。 - value:信号量的初始值。

返回值: - 成功:0,失败:-1

2.信号量P操作

将信号量的值减 1。操作前,先检查信号量(sem)的值是否为 0,若信号量为 0,此函数会阻塞,直到信号量大于 0 时才进行减 1 操作。

#include <semaphore.h> 
//阻塞方式
int sem_wait(sem_t *sem);
//非阻塞方式
int sem_trywait(sem_t *sem);

参数: - sem:信号量的地址。

返回值: - 成功:0,失败:-1

3.信号量V操作

将信号量的值加 1 并发出信号唤醒等待线程(sem_wait())。

#include <semaphore.h> 
int sem_post(sem_t *sem);

参数: - sem:信号量的地址。

返回值: - 成功:0,失败:-1

4.获取信号量的值 获取 sem 标识的信号量的值,保存在 sval 中。

#include <semaphore.h> 
int sem_getvalue(sem_t *sem, int *sval);

参数: - sem:信号量地址。 - sval:保存信号量值的地址。

返回值: - 成功:0,失败:-1

5.销毁信号量 删除 sem 标识的信号量。

#include <semaphore.h> 
int sem_destroy(sem_t *sem);

参数: - sem:信号量地址。

返回值: - 成功:0,失败:-1

实例:

通过信号量实现互斥操作。

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

sem_t sem; //信号量  

//通过信号量实现互斥操作  
void printer(char *str)  
{  
    sem_wait(&sem);//减一  
    while(*str)  
    {  
        putchar(*str);    
        fflush(stdout);  
        str++;  
        sleep(1);  
    }  
    printf("\n");  

    sem_post(&sem);//加一  
}  

void *thread_fun1(void *arg)  
{  
    char *str1 = "hello,world";  
    printer(str1);  
}  

void *thread_fun2(void *arg)  
{  
    char *str2 = "hello,linux";  
    printer(str2);  
}  

int main(void)  
{  
    pthread_t tid1, tid2;  

    sem_init(&sem, 0, 1); //初始化信号量,初始值为 1  

    //创建 2 个线程  
    pthread_create(&tid1, NULL, thread_fun1, NULL);  
    pthread_create(&tid2, NULL, thread_fun2, NULL);  

    //等待线程结束,回收其资源  
    pthread_join(tid1, NULL);  
    pthread_join(tid2, NULL);   

    printf("\n");  
    sem_destroy(&sem); //销毁信号量  

    return 0;  
}  

执行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
hello,world
hello,linux

信号量实现同步。

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

sem_t sem_g, sem_p; //信号量

char ch = 'a';

void *thread_g(void *arg)
{
    while (ch<'z')
    {
        sem_wait(&sem_g);
        ch++;
        sleep(1);
        sem_post(&sem_p);
    }
}

void *thread_p(void *arg)
{
    while (ch<'z')
    {
        sem_wait(&sem_p);
        printf("%c", ch);
        fflush(stdout);
        sem_post(&sem_g);
    }
}

int main(void)
{
    pthread_t tid1, tid2;

    sem_init(&sem_g, 0, 0); //初始化信号量,初始值为 1
    sem_init(&sem_p, 0, 1);
    //创建 2 个线程
    pthread_create(&tid1, NULL, thread_g, NULL);
    pthread_create(&tid2, NULL, thread_p, NULL);

    //等待线程结束,回收其资源
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    printf("\n");
    sem_destroy(&sem_g); //销毁信号量
    sem_destroy(&sem_p);
    return 0;
}

执行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
abcdefghijklmnopqrstuvwxyz