既可以解决多个同类共享资源的互斥问题,也可以解决简易的同步问题
头文件:#include <semaphore.h>
类型:sem_t
初始化:int sem_init(sem_t *sem, int pshared, unsigned int value); //程序中第一次对指定信号量调用p、v操作前必须做初始化
清理:int sem_destroy(sem_t *sem);//程序中不再指定信号量时,应及时调用
P操作: int sem_wait(sem_t *sem);
V操作: int sem_post(sem_t *sem);
功能:见函数名
返回值:成功为0,失败<0
注:pshared参数填零,本来是期望可以实现进程间使用的,Linux未实现
问题:线程1输出多个字符'a',线程2输出多个字符'b',要求打印的结果为abababab...
代码:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
sem_t sem1,sem2; // 初始化信号量
void* pthread1(void *argv){
for(int i = 0;i<10;i++){
sem_wait(&sem1); // 如果信号量是1 就执行下面的代码(然后将sem1 置0),如果是0 就等待
printf("a");
fflush(stdout); // 冲刷缓冲区
sem_post(&sem2); // 发送信号(将sem2 置1)
}
}
void* pthread2(void *argv){
for(int i = 0;i<10;i++){
sem_wait(&sem2);
printf("b");
fflush(stdout); // 冲刷缓冲区
sem_post(&sem1); // 发送信号(将sem1 置1)
}
}
int main(){
pthread_t pth1,pth2;
sem_init(&sem1,0,1); // 初始化信号量
sem_init(&sem2,0,0);
pthread_create(&pth1,NULL,pthread1,NULL);
pthread_create(&pth2,NULL,pthread2,NULL);
pthread_join(pth1,NULL);
pthread_join(pth2,NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
return 0;
}
输出:
问题:建三个线程,线程的ID分别是A,B,C,每个线程在屏幕输出自己的的ID 10 次,并且要求输出的顺序是:ABCABCABC.....(迅雷笔试题)
代码:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
sem_t sem1,sem2,sem3;
void* print_a(void* argv){
for(int i = 0;i<10;i++){
sem_wait(&sem1);
printf("A");
fflush(stdout);
sem_post(&sem2);
}
return NULL;
}
void* print_b(void* argv){
for(int i = 0;i<10;i++){
sem_wait(&sem2);
printf("B");
fflush(stdout);
sem_post(&sem3);
}
return NULL;
}
void* print_c(void* argv){
for(int i = 0;i<10;i++){
sem_wait(&sem3);
printf("C");
fflush(stdout);
sem_post(&sem1);
}
return NULL;
}
int main(){
pthread_t ph1,ph2,ph3;
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
sem_init(&sem3,0,0);
pthread_create(&ph1,NULL,print_a,NULL);
pthread_create(&ph2,NULL,print_b,NULL);
pthread_create(&ph3,NULL,print_c,NULL);
pthread_join(ph1,NULL);
pthread_join(ph2,NULL);
pthread_join(ph3,NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
return 0;
}
输出: