2024-8-15文件IO课后练习

1.POSIX信号量问题

写入端代码:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <semaphore.h>

int main(int argc, const char *argv[])
{
	//获取key值
	key_t key=ftok("./",3);
	if(-1==key){
		perror("获取关键值失败");
		return -1;
	}
	//获取共享内存ID
	int shm_id=shmget(key,2,IPC_CREAT | 0666);
	if(-1==shm_id){
		perror("获取共享内存ID失败");
		return -1;
	}
	//创建有名信号量并初始化
   	sem_t *space = sem_open("/mv_space", O_CREAT, 0666, 1);
    sem_t *data = sem_open("/mv_data", O_CREAT, 0666, 0);

	//映射共享内存
	char *p=shmat(shm_id,NULL,0);
	if(p==(char*)-1){
		perror("映射失败");
		return -1;
	}
	//设置消息内容
	char*msg="0123456789";
	int i=0;

	while(1){
		//把空间信号量-1
		sem_wait(space);

		memcpy(p,msg+i,1);

		//把数据信号量+1
		sem_post(data);

		i=(i+1)%10;
	}
	shmdt(p);
	return 0;
}

读取端代码:

#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <semaphore.h>

sem_t*space=NULL;
sem_t*data=NULL;
void handle_sigint(int sig) {
    printf("\nCaught signal %d. Cleaning up and exiting...\n", sig);
    
    // 关闭信号量
    if (space != SEM_FAILED) {
        sem_close(space);
        sem_unlink("/mv_space");
    }
    if (data != SEM_FAILED) {
        sem_close(data);
        sem_unlink("/mv_data");
    }
	exit(0);
}

int main(int argc, const char *argv[])
{
	// 设置 SIGINT 信号的处理函数
    signal(SIGINT, handle_sigint);

	//获取key值
	key_t key=ftok("./",3);
	if(-1==key){
		perror("获取关键值失败");
		return -1;
	}
	//获取共享内存ID                                                          
	int shm_id=shmget(key,2,IPC_CREAT | 0777);
	if(-1==shm_id){
		perror("获取共享内存ID失败");
		return -1;
	}
	//映射共享内存
	char *p=shmat(shm_id,NULL,0);
	if(p==(char*)-1){
		perror("映射失败");
		return -1;
	}
	//创建有名信号量并初始化
	space=sem_open("/mv_space",O_CREAT);
	data=sem_open("/mv_data",O_CREAT);
	while(1){
		//把数据信号量-1
		sem_wait(data);
		fprintf(stderr,p);
		//把空间信号量+1
		sem_post(space);
	}
	shmdt(p);
	return 0;
}

2.用有名管道和创建子线程实现两个进程间的信息交换 

jack

#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/stat.h>       
#include <fcntl.h>
#include <pthread.h>
#define FIFE_PATH_a "/home/ubuntu/my_fifo_a"
#define FIFE_PATH_b "/home/ubuntu/my_fifo_b"

void *rose_to_jack(void*arg);
int main(int argc, const char *argv[])
{
	//1.判断管道文件是否存在,不存在则创建管道文件;
	if(access(FIFE_PATH_a,R_OK)!=0){
		int ret = mkfifo(FIFE_PATH_a,0777);
		if(ret==-1)
		{
			perror("创建管道文件失败");
			return -1;
		}
	}
	if(access(FIFE_PATH_b,R_OK)!=0){
		int ret = mkfifo(FIFE_PATH_b,0777);
		if(ret==-1)
		{
			perror("创建管道文件失败");
			return -1;
		}
	}
	//2.打开管道文件:
	int fd_a=open(FIFE_PATH_a,O_WRONLY);
	if(-1==fd_a){
		perror("打开文件失败");
		return -1;
	}		
	int fd_b=open(FIFE_PATH_b,O_RDONLY);
	if(-1==fd_b){
		perror("打开文件失败");
		return -1;
	}

	//3.创建线程
	pthread_t TID;
	pthread_create(&TID,NULL,rose_to_jack,(void*)&fd_b);
	
	//4.向管道文件里写入;
	char buf[200];
	while(1)
	{
		memset(buf,0,200);
		fgets(buf,200,stdin);
		if(write(fd_a,buf,strlen(buf))==-1)
		{
			perror("写入文件失败");
			return -1;
			close(fd_a);
		}
		if(strcmp(buf,"byebye\n")==0){
			break;
		}
	}
	close(fd_a);
	return 0;
}

//5.向管道里读取
void *rose_to_jack(void*arg)
{
	char buf[200];
	int fd_b=*(int*)arg;
	while(1)
	{
		memset(buf,0,200);
		if(read(fd_b,buf,sizeof(buf))==-1)
		{
			perror("读取文件失败");
			close(fd_b);
			return NULL;
		}
		printf("rose: %s",buf);
		if(strcmp(buf,"byebye\n")==0){
			break;
		}
	}
	close(fd_b);
	return NULL;
}

2.rose

#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/stat.h>       
#include <fcntl.h>
#include <pthread.h>
#define FIFE_PATH_a "/home/ubuntu/my_fifo_a"
#define FIFE_PATH_b "/home/ubuntu/my_fifo_b"

void *rose_to_jack(void*arg);
int main(int argc, const char *argv[])
{
	//1.判断管道文件是否存在,不存在则创建管道文件;
	if(access(FIFE_PATH_a,R_OK)!=0){
		int ret = mkfifo(FIFE_PATH_a,0777);
		if(ret==-1)
		{
			perror("创建管道文件失败");
			return -1;
		}
	}
	if(access(FIFE_PATH_b,R_OK)!=0){
		int ret = mkfifo(FIFE_PATH_b,0777);
		if(ret==-1)
		{
			perror("创建管道文件失败");
			return -1;
		}
	}
	//2.打开管道文件:
	int fd_a=open(FIFE_PATH_a,O_RDONLY);
	if(-1==fd_a){
		perror("打开文件失败");
		return -1;
	}		
	int fd_b=open(FIFE_PATH_b,O_WRONLY);
	if(-1==fd_b){
		perror("打开文件失败");
		return -1;
	}

	//3.创建线程
	pthread_t TID;
	pthread_create(&TID,NULL,rose_to_jack,(void*)&fd_b);
	
	//4.向管道文件里读取;
	char buf[200];
	while(1)
	{
		memset(buf,0,200);
		if(read(fd_a,buf,sizeof(buf))==-1)
		{
			perror("写入文件失败");
			close(fd_a);
			return -1;
		}
		printf("jack: %s",buf);
		if(strcmp(buf,"byebye\n")==0){
			break;
		}
	}
	close(fd_a);
	return 0;
}

//5.向管道里写入
void *rose_to_jack(void*arg)
{
	char buf[200];
	int fd_b=*(int*)arg;
	while(1)
	{
		memset(buf,0,200);
		fgets(buf,200,stdin);
		if(write(fd_b,buf,strlen(buf))==-1)
		{
			perror("读取文件失败");
			close(fd_b);
			return NULL;
		}
		if(strcmp(buf,"byebye\n")==0){
			break;
		}
	}
	close(fd_b);
	return NULL;
}

代码结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值