IO第4天

发布时间:2023年12月17日

用信号量的方式实现循环倒置和打印,要求倒置一次,打印一次。不允许使用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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。