sem_init
创建并初始化信号量
头文件:
#include <semaphore.h>
原型:
int sem_init(sem_t *sem, int pshared, unsigned int value);
参数:
sem_t *sem:存储创建并初始化后的信号量;
int pshared:共享标识,参数如下:
0:用于线程;
非0:用于进程;
unsigned int value:信号量的初始值;
返回值:
成功,返回0;
失败,返回-1,更新errno;
例程:
static sem_t sem;
if(sem_init(&sem, 0, 3) < 0)
{
perror("sem_init");
return -1;
}
printf("sem初始化成功\n");
sem_destroy
销毁信号量
头文件:
#include <semaphore.h>
原型:
int sem_destroy(sem_t *sem);
参数:
set_t *sem:信号量标识;
返回值:
成功,返回0;
失败,返回-1,设置errno;
例程:
if(sem_destroy(&sem))
{
perror("sem_destroy");
return -1;
}
sem_wait
申请信号量,P操作,-1
1.如果申请前,信号量为0,则该线程阻塞,进入休眠;
2.如果申请前,信号量大于0,则申请成功,信号量-1,函数立即返回;
头文件:
#include <semaphore.h>
原型:
int sem_wait(sem_t *sem);
参数:
sem_t *sem:指定需要申请的信号量;
返回值:
成功,返回0;
失败,返回-1,设置errno;
例程:
if(sem_wait(&sem) < 0)
{
perror("sem_wait");
return -1;
}
sem_post
释放信号量,V操作,+1
头文件:
#include <semaphore.h>
原型:
int sem_post(sem_t *sem);
参数:
sem_t *sem:指定信号量;
返回值:
成功,返回0;
失败,返回-1,更新errno;
例程:
if(sem_post(&sem) < 0)
{
perror("sem_post");
return -1;
}
sem_getvalue
获取指定信号量的值
头文件:
#include <semaphore.h>
原型:
int sem_getvalue(sem_t *sem, int *sval);
参数:
sem_t *sem:指定信号量;
int *sval:存储获取到的信号量的值;
返回值:
成功,返回0;
失败,返回-1,更新errno;
例程:
int sval;
sem_getvalue(&sem, &sval);
printf("sval=%d line=%d\n", sval, __LINE__);
应用例程1
用信号量的方式实现一个线程倒置,一个线程打印,倒置一次打印一次
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
//临界资源(共享资源)
char str[30] = "AAAAAAAAAAA|BBBBBBBBBB";
sem_t sem1;
sem_t sem2;
//打印线程
void* handler1(void* arg)
{
while(1)
{
/*******临界区******/
sem_wait(&sem1);
printf("%s\n", str);
sem_post(&sem2);
/*******临界区******/
}
pthread_exit(NULL);
}
//倒置线程
void* handler2(void* arg)
{
char* start = NULL;
char* end = NULL;
char temp = 0;
while(1)
{
start = str;
end = str+strlen(str)-1;
/*******临界区******/
sem_wait(&sem2);
while(start < end)
{
temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
sem_post(&sem1);
/*******临界区******/
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//sem1控制打印
if(sem_init(&sem1, 0, 1) < 0)
{
perror("sem_init");
return -1;
}
//sem2控制倒置
if(sem_init(&sem2, 0, 0) < 0)
{
perror("sem_init");
return -1;
}
pthread_t tid1, tid2;
if(pthread_create(&tid1, NULL, handler1, NULL) != 0)
{
perror("pthread_create");
return -1;
}
if(pthread_create(&tid2, NULL, handler2, NULL) != 0)
{
perror("pthread_create");
return -1;
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
//销毁信号量
sem_destroy(&sem1);
sem_destroy(&sem2);
return 0;
}
应用例程2
创建两个线程,实现
- 将一个文档的内容打印到终端上。类似 cat一个文件。
- 打印完毕后,退出进程。
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
//共享资源
FILE *fp = NULL;
char c = 0;
//信号量
sem_t sem_r,sem_w;
//线程1,读数据
void *handler1(void *arg)
{
while(1)
{
sem_wait(&sem_r);
c = fgetc(fp);
fflush(fp);
if(c == EOF)
{
printf("线程1-->读取完毕\n");
sem_post(&sem_w);
break;
}
sem_post(&sem_w);
}
pthread_exit(NULL);
}
//线程2,写数据-->打印到终端上
void *handler2(void *arg)
{
while(1)
{
sem_wait(&sem_w);
if(c == EOF)
{
printf("线程2-->打印完毕\n");
break;
}
fputc(c,stdout);
fflush(fp);
sem_post(&sem_r);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
fp = fopen("./cat.c","r");
if(sem_init(&sem_r,0,1) < 0)
{
perror("sem_init_r");
return -1;
}
if(sem_init(&sem_w,0,0) < 0)
{
perror("sem_init_w");
return -1;
}
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,handler1,NULL)!=0)
{
perror("pthread_create_tid1");
return -1;
}
if(pthread_create(&tid2,NULL,handler2,NULL)!=0)
{
perror("pthread_create_tid2");
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁信号量
sem_destroy(&sem_r);
sem_destroy(&sem_w);
return 0;
}
结果
本文链接:https://shengto.top/c/semaphore_routine.html
转载时须注明出处及本声明