2023/3/2 互斥锁、条件变量、信号量练习
作业
1.将一个文件中的数据打印到终端上,类似cat个文件。要求如下
a. A线程读取文件中的数据
b. B线程将A线程读取到的数据打印到终端上
c.文件打印完毕后,结束进程。
#include "head.h"
sem_t sem1,sem2;
int fd;
char buf[32];
void* thread1(void* arg)
{
ssize_t res = 0;
while(1)
{
sem_wait(&sem1);
memset(buf,0,sizeof(buf));
res = read(fd,buf,sizeof(buf));
if(0 == res)
{
//printf("%d\n",strlen(buf));
sem_post(&sem2);
break;
}
sem_post(&sem2);
}
pthread_exit(NULL);
}
void* thread2(void* arg)
{
while(1)
{
sem_wait(&sem2);
if(strlen(buf) == 0)
{
sem_post(&sem1);
break;
}else
{
write(1,buf,strlen(buf));
}
sem_post(&sem1);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
sem_init(&sem1,0,1);
sem_init(&sem2,0,0);
fd = open(argv[1],O_RDONLY);
if(fd < 0)
{
ERR_MSG("open");
return -1;
}
pthread_t tid1,tid2;
int ret1,ret2;
ret1 = pthread_create(&tid1,NULL,thread1,NULL);
if(ret1 != 0)
{
fprintf(stderr,"pthread_create thread1 failed\n");
return -1;
}
pthread_detach(tid2);
ret2 = pthread_create(&tid1,NULL,thread2,NULL);
if(ret2 != 0)
{
fprintf(stderr,"pthread_create thread2 failed\n");
return -1;
}
pthread_join(tid1,NULL);
//pthread_join(tid2,NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
if(close(fd) < 0)
{
ERR_MSG("close");
return -1;
}
return 0;
}
2.用条件变量实现,有编号为ABC的三个线程,线程内分别打印自己的线程编号,要求打印的顺序为ABC。
a.提示:多个条件变量
#include "head.h"
//创建互斥锁
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;
int flag = 0;
void* threadA(void* arg)
{
while(1)
{
//*******临界区*********//
//上锁
pthread_mutex_lock(&mutex);
if(flag%3 != 0)
{
//解开互斥锁,同时阻塞当前线程,让线程进入休眠阶段
//等待被唤醒
pthread_cond_wait(&cond1,&mutex);
}
printf("A");
flag++;
//唤醒睡在指定条件变量上的线程
pthread_cond_signal(&cond2);
//解锁
pthread_mutex_unlock(&mutex);
//pthread_cond_signal(&cond);
//*******临界区*********//
}
pthread_exit(NULL);
}
void* threadB(void* arg)
{
while(1)
{
//*******临界区*********//
//上锁
pthread_mutex_lock(&mutex);
if(flag%3 != 1)
{
//解开互斥锁,同时阻塞当前线程,让线程进入休眠阶段
//等待被唤醒
pthread_cond_wait(&cond2,&mutex);
}
printf("B");
flag++;
//唤醒睡在指定条件变量上的线程
pthread_cond_signal(&cond3);
//解锁
pthread_mutex_unlock(&mutex);
//pthread_cond_signal(&cond);
//*******临界区*********//
}
pthread_exit(NULL);
}
void* threadC(void* arg)
{
while(1)
{
//*******临界区*********//
//上锁
pthread_mutex_lock(&mutex);
if(flag%3 != 2)
{
//解开互斥锁,同时阻塞当前线程,让线程进入休眠阶段
//等待被唤醒
pthread_cond_wait(&cond3,&mutex);
}
printf("C\n");
flag++;
//唤醒睡在指定条件变量上的线程
pthread_cond_signal(&cond1);
//解锁
pthread_mutex_unlock(&mutex);
//pthread_cond_signal(&cond);
//*******临界区*********//
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_t tid1,tid2,tid3;
int ret1,ret2,ret3;
ret1 = pthread_create(&tid1,NULL,threadA,NULL);
if(ret1 != 0)
{
fprintf(stderr,"pthread_create threadA failed __%d__\n",__LINE__);
return -1;
}
ret2 = pthread_create(&tid2,NULL,threadB,NULL);
if(ret2 != 0)
{
fprintf(stderr,"pthread_create threadB failed __%d__\n",__LINE__);
return -1;
}
ret3 = pthread_create(&tid3,NULL,threadC,NULL);
if(ret3 != 0)
{
fprintf(stderr,"pthread_create threadC failed __%d__\n",__LINE__);
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
pthread_join(tid3,NULL);
//销毁互斥锁
pthread_mutex_destroy(&mutex);
//销毁条件变量
pthread_cond_destroy(&cond1);
pthread_cond_destroy(&cond2);
pthread_cond_destroy(&cond3);
return 0;
}
3.要求用信号量的方式实现,打印一次倒置一次。 不允许使用flag
#include "head.h"
#define MAXSIZE 2
char buf[]="1234567";
sem_t sem[MAXSIZE];
void strRev()
{
int i,j;
char temp;
i = 0;
j = strlen(buf)-1;
while(i<j)
{
temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
i++;
j--;
}
}
void* thread1(void* arg)
{
while(1)
{
sem_wait(&sem[0]);
printf("A:");
puts(buf);
sem_post(&sem[1]);
}
pthread_exit(NULL);
}
void* thread2(void* arg)
{
while(1)
{
sem_wait(&sem[1]);
strRev();
sem_post(&sem[0]);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
sem_init(&sem[0],0,1);
sem_init(&sem[1],0,0);
pthread_t tid1,tid2;
int ret1,ret2;
ret1 = pthread_create(&tid1,NULL,thread1,NULL);
if(ret1 != 0)
{
fprintf(stderr,"pthread_create thread1 failed\n");
return -1;
}
ret2 = pthread_create(&tid1,NULL,thread2,NULL);
if(ret2 != 0)
{
fprintf(stderr,"pthread_create thread2 failed\n");
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
for(int i=0;i<MAXSIZE;i++)
{
sem_destroy(&sem[i]);
}
return 0;
}