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