IO第4天
2023-12-17 22:49:30
用信号量的方式实现循环倒置和打印,要求倒置一次,打印一次。不允许使用flag
使用信号量来控制运行顺序:两个信号仓共用一个信号量,A信号仓用完了给B用
#include <myhead.h>
sem_t sid1,sid2;
char arr[]="1234567";
void* pthreadA(void* arg) //void* arg=&sid
{
while(1){
//-1 P操作
if(sem_wait(&sid1)<0){
perror("sem_wait");
pthread_exit(NULL);
}
printf("%s\n",arr);
//+1 V操作
if(sem_post(&sid2)<0){
perror("sem_wait");
pthread_exit(NULL);
}
}
pthread_exit(NULL);
}
void* pthreadB(void* arg) //void* arg=&sid
{
while(1){
//-1 P操作
if(sem_wait(&sid2)<0){
perror("sem_wait");
pthread_exit(NULL);
}
char temp;
for(int i=0,j=strlen(arr)-1;i<j;i++,j--){
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//+1 V操作
if(sem_post(&sid1)<0){
perror("sem_wait");
pthread_exit(NULL);
}
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_t pid1,pid2;
if(sem_init(&sid1,0,1)<0){
perror("sem_init");
return -1;
}
//声明两个信号仓,两个信号仓共用一个信号
if(sem_init(&sid2,0,0)<0){
perror("sem_init");
return -1;
}
if(pthread_create(&pid1,NULL,pthreadA,&sid1)!=0){
printf("pthreadA create fail\n");
return -1;
}
if(pthread_create(&pid2,NULL,pthreadB,&sid2)!=0){
printf("pthreadB create fail\n");
return -1;
}
pthread_join(pid1,NULL);
pthread_join(pid2,NULL);
sem_destroy(&sid1);
sem_destroy(&sid2);
return 0;
}
完成图片拷贝,要求一个线程拷贝一半,另一个线程拷贝另一半。
提示:找临界资源,找临界区,对临界区上锁解锁即可
#include <myhead.h>
#define muid pthread_mutex_t
struct stat statbuf;
int pid_r,pid_w;
pthread_mutex_t mutex;
//上半部分
void* pthreadA(void* arg){ //void* arg=&mutex
//上锁
pthread_mutex_lock(&mutex);
//重置读取位置
lseek(pid_r,0,SEEK_SET);
//重置写入位置
lseek(pid_w,0,SEEK_SET);
//写入前半部分
char str;
for(int i=0;i<statbuf.st_size/2;i++){
read(pid_r,&str,sizeof(str));
write(pid_w,&str,sizeof(str));
}
//解锁
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
//下半部分
void* pthreadB(void* arg){ //void* arg=&mutex
//上锁
pthread_mutex_lock(&mutex);
//重置读取位置
char str;
lseek(pid_r,statbuf.st_size/2,SEEK_SET);
lseek(pid_w,statbuf.st_size/2,SEEK_SET);
//写入后半部分
for(int i=statbuf.st_size/2;i<statbuf.st_size;i++)
{
read(pid_r,&str,sizeof(str));
write(pid_w,&str,sizeof(str));
}
//解锁
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_t tid1,tid2;
//打开源文件
if((pid_r=open("./cat.jpg",O_RDONLY))<0){
perror("open");
pthread_exit(NULL);
}
if((pid_w=open("./cat1.jpg",O_WRONLY|O_CREAT|O_TRUNC,0664))<0){
perror("open");
pthread_exit(NULL);
}
//获取文件属性大小
stat("./cat.jpg",&statbuf);
//创建锁
pthread_mutex_init(&mutex,NULL);
//创建线程
if(pthread_create(&tid1,NULL,pthreadA,NULL)!=0){
printf("create pthreadA file\n");
return -1;
}
if(pthread_create(&tid2,NULL,pthreadB,NULL)!=0){
printf("create pthreadB file\n");
return -1;
}
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁锁
pthread_mutex_destroy(&mutex);
//关闭文件
close(pid_r);
close(pid_w);
return 0;
}
遇到的问题:1、运算符优先级:=的优先级最低,需要括起来再进行比较运算
2、同一个写入文件,用了打开清空就不能再在另一个线程打开清空了,最好写主函数里
3、for循环的循环头括号后面如果加“;”,那么这个for循环只会运行一次
创建两个线程,要求一个线程从文件中读取数据,另一个线程将读取到的数据打印到终端,类似cat一个文件。文件cat完毕后,要结束进程
提示:读到一次数据,打印一次数据
#include <myhead.h>
sem_t sid1,sid2;
FILE* pid;
char buf;
struct stat statbuf;
void* pthreadA(void* arg){
printf("size:%d\n",statbuf.st_size);
int i=0;
while(i<statbuf.st_size){
//p操作 -1
if(sem_wait(&sid1)<0){
perror("sem_wait");
pthread_exit(NULL);
}
fseek(pid,i,SEEK_SET);
buf=fgetc(pid);
//v操作 +1
if(sem_post(&sid2)<0){
perror("sem_post");
pthread_exit(NULL);
}
i++;
}
pthread_exit(NULL);
}
void* pthreadB(void* arg){
int i=0;
while(i<statbuf.st_size)
{
//p操作 -1
if(sem_wait(&sid2)<0){
perror("sem_wait");
pthread_exit(NULL);
}
printf("%c",buf);
//v操作 +1
if(sem_post(&sid1)<0){
perror("sem_post");
pthread_exit(NULL);
}
i++;
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//打开文件
pid=fopen("./1.txt","r");
stat("./1.txt",&statbuf);
//创建信号灯
int res;
if((res=sem_init(&sid1,0,1)<0)){
perror("sem_init");
return -1;
}
if((res=sem_init(&sid2,0,0)<0)){
perror("sem_init");
return -1;
}
//创建A线程
pthread_t tid1,tid2;
if((res=pthread_create(&tid1,NULL,pthreadA,NULL))<0){
printf("create pthreadA fail\n");
return -1;
}
//创建B线程
if((res=pthread_create(&tid2,NULL,pthreadB,NULL))<0){
printf("create pthreadB fail\n");
return -1;
}
//线程回收
pthread_join(tid1,NULL);
pthread_join(tid2,NULL);
//销毁信号灯
sem_destroy(&sid1);
sem_destroy(&sid2);
//关闭文件
fclose(pid);
return 0;
}
只要while循环体没结束,就会一直按照顺序读写,直到满足条件退出
文章来源:https://blog.csdn.net/weixin_54006234/article/details/135023906
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!