一、创建两个线程,实现将一个文件的内容打印到终端上,类比cat指令文件
a.一个线程读取文件中的内容
b.另一个线程将读取到的内容打印到终端上。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<semaphore.h>
#include<pthread.h>
//将一个文件的数据打印到终端上,类似cat一个文件
//一个线程读取文件的数据
//另一个线程打印文件中的数据
sem_t sem;
sem_t sem1;
char buf[128]="";
void *callback_print(void*arg)
{
while(1)
{
//p操作
if(sem_wait(&sem)<0)
{
perror("sem_wait");
break;
}
printf("%s\n",buf);
//v操作
if(sem_post(&sem1)<0)
{
perror("sem_post");
break;
}
}
}
int main(int argc, const char *argv[])
{
if(sem_init(&sem,0,1)<0)//创建信号量
{
perror("sem_init");
return -1;
}
if(sem_init(&sem1,0,0)<0)
{
perror("sem_init");
return -1;
}
pthread_t tid;
int res=pthread_create(&tid,NULL,callback_print,NULL);//创建一个打印线程
if(res!=0)
{
return -1;
}
FILE*fd=fopen("./1.c","r");
if(fd==NULL)
{
perror("fopen");
return -1;
}
while(1)
{
if(sem_wait(&sem1)<0)//P操作
{
perror("sem_wait");
return -1;
}
if(fgets(buf,sizeof(buf),fd)==NULL)
{
break;
}
if(sem_post(&sem)<0)//v操作
{
perror("sem_post");
return -1;
}
}
pthread_cancel(tid);
pthread_join(tid,NULL);
//关闭文件
fclose(fd);
sem_destroy(&sem);
sem_destroy(&sem1);
return 0;
}
二、使用条件变量的方式
- 现有ID号为a b c的三个线程;
- 每个线程的任务都是循环打印自己id号;
- 打印的顺序为abc;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
//用条件变量的形式实现:现有ID号a,b,c三个线程每个线程的任务循环打印自己的ID号
//要求打印顺序为a,b,c
//创建互斥锁
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
//创建条件变量
pthread_cond_t cond1=PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2=PTHREAD_COND_INITIALIZER;
pthread_cond_t cond3=PTHREAD_COND_INITIALIZER;
pthread_t tid1;
pthread_t tid2;
pthread_t tid3;
int flag=0;//限制访问时机 不是直接
void *callback1(void*arg)
{
while(1)
{
/临界区///
pthread_mutex_lock(&mutex);//上锁
//当不是当前线程访问的时机,则当前时机休眠
if(flag!=0)
{
//设置休眠条件(唤醒条件),解开互斥锁
//休眠,等待被唤醒
pthread_cond_wait(&cond1,&mutex);
}
printf("tid1=%ld\n",tid1);
flag=1;//修改运行时机
pthread_cond_signal(&cond2);//通过条件变量唤醒cond2线程
pthread_mutex_unlock(&mutex);//解锁
临界区//
}
}
void*callback2(void*arg)
{
while(1)
{
/临界区///
pthread_mutex_lock(&mutex);//上锁
if(flag!=1)
{
pthread_cond_wait(&cond2,&mutex);
}
printf("tid2=%ld\n",tid2);
flag=2;
pthread_cond_signal(&cond3);
pthread_mutex_unlock(&mutex);//解锁
临界区//
}
}
void*callback3(void*arg)
{
while(1)
{
/临界区///
pthread_mutex_lock(&mutex);//上锁
if(flag!=2)
{
pthread_cond_wait(&cond3,&mutex);
}
printf("tid3=%ld\n",tid3);
flag=0;
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&mutex);//解锁
临界区//
}
}
int main(int argc, const char *argv[])
{
int res=pthread_create(&tid1,NULL,callback1,NULL);//a线程
if(res!=0)
{
fprintf(stderr,"pthread_create faild line:%d",__LINE__);
return -1;
}
int ret=pthread_create(&tid2,NULL,callback2,NULL);//b线程
if(ret!=0)
{
fprintf(stderr,"pthread_create faild line:%d",__LINE__);
return -1;
}
int rex=pthread_create(&tid3,NULL,callback3,NULL);//c线程
if(rex!=0)
{
fprintf(stderr,"pthread_create faild line:%d",__LINE__);
return -1;
}
//堵塞
pthread_join(tid1,NULL);
//销毁互斥锁
pthread_mutex_destroy(&mutex);
//销毁条件变量
pthread_cond_destroy(&cond1);
pthread_cond_destroy(&cond2);
pthread_cond_destroy(&cond3);
return 0;
}