作业
1.将一个文件中的数据打印到终端上类似cat一个文件,要求如下
(1)a线程读取文件中的数据
(2)B线程将A线程读取到的数据打印到终端上
(3)文件打印完毕后,结束进程
方法1:用互斥锁和条件变量
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int flag=0;
char c;
struct info{
int file_r;
off_t size;
};
void* callback_A(void* arg)//arg=©
{
struct info *info = (struct info *)arg;
for(int i=0;i<info->size;i++)
{
//---------临界区------------
//上锁
pthread_mutex_lock(&mutex);
if(0!=flag)
{
pthread_cond_wait(&cond,&mutex);
}
read(info->file_r,&c,1);
flag=1;
//---------------临界区----------
pthread_cond_signal(&cond);
//开锁
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void* callback_B(void* arg)
{
struct info * info=(struct info *)arg;
for(int i=0;i<info->size;i++)
{
//上锁
pthread_mutex_lock;
if(1!=flag)
{
//
pthread_cond_wait(&cond,&mutex);
}
//写入终端
// write(1,&c,1);
printf("%c", c);
flag=0;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//打开文件
struct info copy;
copy.file_r = open("./sem.c",O_RDONLY);
if(copy.file_r<0 )
{
perror("open");
return -1;
}
//计算文件大小
copy.size = lseek(copy.file_r,0,SEEK_END);
//创建线程
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,callback_A,©)!=0)
{
perror("callback_A create failed\n");
return -1;
}
if(pthread_create(&tid2,NULL,callback_B,©)!=0)
{
perror("callback_B create failed\n");
return -1;
}
//创建一个互斥锁
if(pthread_mutex_init(&mutex,NULL)!=0)
{
perror("pthread_mutex_init error");
return -1;
}
//创建一个条件标量
if(pthread_cond_init(&cond,NULL)!=0)
{
perror("pthread_cond_init error");
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁互斥所
pthread_mutex_destroy(&mutex);
//销毁条件变量
pthread_cond_destroy(&cond);
//关闭文件
close(copy.file_r);
return 0;
}
方法2:用信号量
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
char c;
sem_t sem1;
sem_t sem2;
struct info{
int file_r;
off_t size;
};
void* callback_A(void* arg)//arg=©
{
struct info *info = (struct info *)arg;
for(int i=0;i<info->size;i++)
{
//---------临界区------------
sem_wait(&sem1);
read(info->file_r,&c,1);
// printf("%c",c);
sem_post(&sem2);
//---------------临界区----------
}
pthread_exit(NULL);
}
void* callback_B(void* arg)
{
struct info * info=(struct info *)arg;
for(int i=0;i<info->size;i++)
{
//写入终端
sem_wait(&sem2);
write(1,&c,1);
// printf("%c",c);
// fflush(stdout);
sem_post(&sem1);
// printf("-----------\n");
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//打开文件
struct info copy;
copy.file_r = open("./sem.c",O_RDONLY);
if(copy.file_r<0 )
{
perror("open");
return -1;
}
//计算文件大小
copy.size = lseek(copy.file_r,0,SEEK_END);
lseek(copy.file_r,0,SEEK_SET);
//创建线程
pthread_t tid1,tid2;
if(pthread_create(&tid1,NULL,callback_A,©)!=0)
{
perror("callback_A create failed\n");
return -1;
}
if(pthread_create(&tid2,NULL,callback_B,©)!=0)
{
perror("callback_B create failed\n");
return -1;
}
//创建信号量
if(sem_init(&sem1,0,1) != 0)
{
perror("sem_init1 error");
return -1;
}
if(sem_init(&sem2,0,0) != 0)
{
perror("sem_init2 error");
return -1;
}
//创建互斥
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//关闭文件
close(copy.file_r);
return 0;
}
2、用条件变量实现,有编号为ABC的三个线程,线程内分别打印自己的线程编号,要求打印的顺序为ABC
(1)提示:使用多个条件变量
#include <stdio.h>
#include <pthread.h>
#include <error.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* callBack_A(void* arg)
{
while(1)
{
//上锁
pthread_mutex_lock(&mutex);
if(flag != 0)
{
pthread_cond_wait(&cond1,&mutex);
}
printf("A");
flag=1;
pthread_cond_signal(&cond2);
//关锁
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void* callBack_B(void* arg)
{
while(1)
{
//上锁
pthread_mutex_lock(&mutex);
if(flag != 1)
{
pthread_cond_wait(&cond2,&mutex);
}
printf("B");
flag=2;
pthread_cond_signal(&cond3);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void* callBack_C(void* arg)
{
while(1)
{
//上锁
pthread_mutex_lock(&mutex);
if(flag != 2)
{
pthread_cond_wait(&cond3,&mutex);
}
printf("C");
printf("\n");
flag=0;
pthread_cond_signal(&cond1);
//关锁
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//创建线程
pthread_t tid1,tid2,tid3;
if(pthread_create(&tid1,NULL,callBack_A,NULL)!=0)
{
perror("callBack_A create error");
return -1;
}
if(pthread_create(&tid2,NULL,callBack_B,NULL)!=0)
{
perror("callBack_Bcreate error");
return -1;
}
if(pthread_create(&tid3,NULL,callBack_C,NULL)!=0)
{
perror("callBack_C create error");
return -1;
}
//创建一个互斥锁
if(pthread_mutex_init(&mutex,NULL)!=0)
{
perror("mutex init error");
return -1;
}
//创建条件标量
if(pthread_cond_init(&cond1,NULL)!=0)
{
perror("cond1 init error");
return -1;
}
if(pthread_cond_init(&cond2,NULL)!=0)
{
perror("cond2 init error");
return -1;
}
if(pthread_cond_init(&cond3,NULL)!=0)
{
perror("cond3 init error");
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 <stdio.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
char buf[]="1234567";
sem_t sem1;
sem_t sem2;
void* callBack_print(void* arg)
{
while(1)
{
sem_wait(&sem1);
printf("%s\n",buf);
sem_post(&sem2);
sem_post(&sem1);
}
pthread_exit(NULL);
}
void* callBack_swap(void* arg)
{
while(1)
{
char temp;
int i=0,j=strlen(buf)-1;
while(i<j)
{
temp=buf[i];
buf[i]=buf[j];
buf[j]=temp;
i++;j--;
}
// printf("%s\n",buf);
sem_post(&sem1);
sem_wait(&sem2);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
sem_init(&sem1,0,1);
sem_init(&sem2,0,1);
pthread_t tid1,tid2;
//创建线程
if(pthread_create(&tid1,NULL,callBack_print,NULL)!=0)
{
fprintf(stderr,"pthread_create error __%d__\n",__LINE__);
return -1;
}
if(pthread_create(&tid2,NULL,callBack_swap,NULL)!=0)
{
fprintf(stderr,"pthread_create error __%d__\n",__LINE__);
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
return 0;
}
结果: