代码实现如下:
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//初始化信号量
sem_t sem1;
sem_t sem2;
//临界资源
//int fd_r;
FILE *fd_r;
char buf[20] = "";
size_t res = 0;
void *funcA(void *arg)
{
while(1)
{
/**************临界区***************/
if(sem_wait(&sem1) < 0) //P操作
{
perror("sem_wait");
return NULL;
}
//res = read(fd_r,buf,sizeof(buf));
res = fread(buf,1,sizeof(buf),fd_r);
if(sem_post(&sem2) < 0) //V操作
{
perror("sem_post");
return NULL;
}
/**************临界区***************/
if(res < 1) //注:退出条件要放在锁外,否则会形成死锁,倒置线程休眠,程序无法退出
break;
}
pthread_exit(NULL);
}
void *funcB(void *arg)
{
while(1)
{
/**************临界区***************/
if(sem_wait(&sem2) < 0) //P操作
{
perror("sem_wait");
return NULL;
}
//write(1,buf,res);
fwrite(buf,1,res,stdout);
if(sem_post(&sem1) < 0) //V操作
{
perror("sem_post");
return NULL;
}
/**************临界区***************/
if(res < 1)
break;
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//创建一个信号量
if(sem_init(&sem1,0,1) < 0)
{
perror("sem_init");
return -1;
}
if(sem_init(&sem2,0,0) < 0)
{
perror("sem_init");
return -1;
}
//打开一个文件,只读
/*fd_r = open("./sem_cat.c",O_RDONLY);
if(fd_r < 0)
{
perror("open");
return -1;
}*/
fd_r = fopen("./sem_cat.c","r");
if(NULL == fd_r)
{
perror("fopen");
return -1;
}
//创建一个线程A用于读取文件中内容
pthread_t A;
if(pthread_create(&A,NULL,funcA,NULL) != 0)
{
fprintf(stderr,"pthread_create failed\n");
return -1;
}
//创建一个线程B用于将A线程中读取到的数据打印到终端上
pthread_t B;
if(pthread_create(&B,NULL,funcB,NULL) != 0)
{
fprintf(stderr,"pthread_create failed\n");
return -1;
}
pthread_join(A,NULL);
pthread_join(B,NULL);
//关闭文件
//close(fd_r);
fclose(fd_r);
//销毁信号量
sem_destroy(&sem1);
sem_destroy(&sem2);
return 0;
}
运行结果如下: