20230307 作业

作业1

创建两个进程,定义一个共享内存,内存中存储char str[10]= “1234567”;要求如下

A循环打印str;

B循环倒置str; 不能使用辅助数组;

要求出现的结果没有乱序,只能出现 1234567 7654321

不允许使用sleep函数

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/sem.h>
#include <signal.h>

#define SHM_SIZE 10  // 共享内存大小

int semid_mutex=0;
int semid_lock=0;
void *shmaddr = NULL;
int shmid=0;

void handler(int sig){
	//进程终止后,删除共享内存和信号灯集
	if(SIGQUIT == sig || SIGINT == sig || SIGKILL == sig){
		
		//printf("thread %d:\n",getpid());
		
		if(semctl(semid_mutex,0,IPC_RMID) < 0){
			perror("semctl");
		}else{
			printf("semid=%d deleted\n",semid_mutex);
		}

		if(semctl(semid_lock,0,IPC_RMID) < 0){
			perror("semctl");
		}else{
			printf("semid=%d deleted\n",semid_lock);
		}

		// 解除共享内存映射
		if (shmdt(shmaddr) <0) {
			perror("shmdt");
		}else{
			printf("shmaddr=%p deleted\n",shmaddr);
		}

		// 删除共享内存
		if (shmctl(shmid, IPC_RMID, NULL) <0) {
			perror("shmctl");
		}else{
			printf("shmid=%d deleted\n",shmid);
		}
		
		system("ipcs");

		exit(0);
	}
}

int main()
{
	key_t key = ftok("/home/ubuntu/hqyj/",'B');
	if(key < 0){
		perror("ftok");
		return -1;
	}
	printf("key=%d\n",key);

	// 创建共享内存
	if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0777)) < 0) {
		perror("shmget");
		return -1;
	}
	printf("shmid=%d\n",shmid);

	shmaddr = shmat(shmid,NULL,0);  // 共享内存地址
	// 映射共享内存
	if( (void *)-1 == shmaddr) {
		perror("shmat");
		return -1;
	}

	char *straddr = (char *)shmaddr;
	strcpy(straddr,"1234567");
	int len = strlen(straddr);

	key_t key_1 = ftok("/home/ubuntu/hqyj/",'C');
	if(key_1 < 0){
		perror("ftok");
		return -1;
	}
	printf("key_1=%d\n",key_1);

	key_t key_2 = ftok("/home/ubuntu/hqyj/",'D');
	if(key_2 < 0){
		perror("ftok");
		return -1;
	}
	printf("key_2=%d\n",key_2);

	semid_mutex = semget(key_1,1,IPC_CREAT | 0777);
	semid_lock  = semget(key_2,1,IPC_CREAT | 0777);
	printf("sem_mutex=%d\n",semid_mutex);
	printf("sem_lock =%d\n",semid_lock );
	if(semid_lock < 0 || semid_mutex < 0){
		perror("semget");
		return -1;
	}
	
	struct sembuf op_p = {0,-1,1};
	struct sembuf op_v = {0,1,1};
	
	if(semop(semid_mutex,&op_v,1)<0){
		perror("semop");
		return -1;
	}

	pid_t pid = fork();
	if(pid < 0){
		perror("fork");
		return -1;
	}

	if(pid == 0){
		int i;
		char t;

		while(1){
			semop(semid_lock,&op_p,1);

			for(i=0;i<len/2;i++){
				t=*(straddr+i);
				*(straddr+i)=*(straddr+len-1-i);
				*(straddr+len-1-i)=t;
			}

			semop(semid_mutex,&op_v,1);
		}

	}else{
		
		__sighandler_t res = signal(SIGQUIT,handler);
		if(SIG_ERR == res){
			perror("signal");
			return -1;
		}
		printf("父进程已捕获信号SIGQUIT\n");
		
		int i=0;

		while(1){
			semop(semid_mutex,&op_p,1);

			printf("%s\n",straddr);

			semop(semid_lock,&op_v,1);

			if(++i == 5){
				raise(SIGQUIT);
			}
		}
	}

	return 0;
}

ubuntu@ubuntu:20230306_ipc$ ./a.out 
key=1107366178
shmid=60
key_1=1124143394
key_2=1140920610
sem_mutex=8
sem_lock =9
父进程已捕获信号SIGQUIT
1234567
7654321
1234567
7654321
1234567
semid=8 deleted
semid=9 deleted
shmaddr=0x7f4cd4a55000 deleted
shmid=60 deleted

--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息      
0x41011122 2          ubuntu     664        0            0           

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态      
0x00000000 11         ubuntu     600        268435456  2          目标       
0x00000000 16         ubuntu     600        524288     2          目标       
0x00000000 20         ubuntu     600        524288     2          目标       
0x00000000 21         ubuntu     600        524288     2          目标       
0x00000000 22         ubuntu     600        524288     2          目标       
0x00000000 30         ubuntu     600        524288     2          目标       
0x00000000 36         ubuntu     600        524288     2          目标       
0x00000000 37         ubuntu     600        16777216   2          目标       
0x00000000 38         ubuntu     600        524288     2          目标       
0x00000000 39         ubuntu     700        18908      2          目标       
0x00000000 55         ubuntu     777        1024       1          目标       
0x00000000 58         ubuntu     700        200564     2          目标       
0x00000000 59         ubuntu     777        10         1          目标       
0x00000000 60         ubuntu     777        10         1          目标       

--------- 信号量数组 -----------
键        semid      拥有者  权限     nsems    

作业2

用消息队列实现AB通信,输入quit结束

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

struct msgbuf{
	long mtype;
	char mtext[100];
};

int msgid_1 = 0;
int msgid_2 = 0;

void handler(int sig){
	if(SIGUSR1 == sig){
		if(msgctl(msgid_1, IPC_RMID, NULL) < 0){
			perror("msgctl");
		}else{
			printf("msgid_1=%d deleted\n",msgid_1);
		}

		if(msgctl(msgid_2, IPC_RMID, NULL) < 0){
			perror("msgctl");
		}else{
			printf("msgid_2=%d deleted\n",msgid_2);
		}
		exit(1);
	}
}
int main(int argc, const char *argv[])
{
	key_t key_1 = ftok("/home/ubuntu/hqyj/",'A');
	key_t key_2 = ftok("/home/ubuntu/hqyj/",'B');

	if(key_1 < 0 || key_2 < 0){
		perror("ftok");
		return -1;
	}
	printf("key_1=%d\n",key_1);

	printf("key_2=%d\n",key_2);

	msgid_1 = msgget(key_1,IPC_CREAT | 0664);
	msgid_2 = msgget(key_2,IPC_CREAT | 0664);
	if(msgid_1 < 0 || msgid_2 < 0){
		perror("msgget");
		return -1;
	}
	printf("msgid_1 = %d\n",msgid_1);
	printf("msgid_2 = %d\n",msgid_2);

	ssize_t res;
	struct msgbuf buf;
	struct msgbuf rcv;

	__sighandler_t res_1 = signal(SIGUSR1,handler);
	if(SIG_ERR == res_1){
		perror("signal");
		return -1;
	}

	pid_t pid = fork();
	if(pid < 0){
		perror("fork");
		return -1;
	}
	if(pid > 0){
		
		while(1){
			res = msgrcv(msgid_1,&rcv,sizeof(rcv.mtext),0,0);

			if(res < 0){
				perror("msgrcv");
				return -1;
			}

			if(strcmp(rcv.mtext,"quit") == 0){
				kill(getpid(),SIGUSR1);
			}
			printf("rcv msg type=%ld text=%s\n",rcv.mtype,rcv.mtext);
		}
	}else{
		while(1){
			buf.mtype = 1;

			scanf("%s",buf.mtext);

			if(msgsnd(msgid_2,&buf,sizeof(buf.mtext),0) < 0){
				perror("msgsnd");
				return -1;
			}
		
			if(strcmp(buf.mtext,"quit") == 0){
				kill(getpid(),SIGUSR1);
			}
		}
	}

	return 0;
}

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

struct msgbuf{
	long mtype;
	char mtext[100];
};

int msgid_1 = 0;
int msgid_2 = 0;

void handler(int sig){
	if(SIGUSR1 == sig){
		if(msgctl(msgid_1, IPC_RMID, NULL) < 0){
			perror("msgctl");
		}else{
			printf("msgid_1=%d deleted\n",msgid_1);
		}

		if(msgctl(msgid_2, IPC_RMID, NULL) < 0){
			perror("msgctl");
		}else{
			printf("msgid_2=%d deleted\n",msgid_2);
		}
		exit(1);
	}
}
int main(int argc, const char *argv[])
{
	key_t key_1 = ftok("/home/ubuntu/hqyj/",'A');
	key_t key_2 = ftok("/home/ubuntu/hqyj/",'B');

	if(key_1 < 0 || key_2 < 0){
		perror("ftok");
		return -1;
	}
	printf("key_1=%d\n",key_1);

	printf("key_2=%d\n",key_2);

	msgid_1 = msgget(key_1,IPC_CREAT | 0664);
	msgid_2 = msgget(key_2,IPC_CREAT | 0664);
	if(msgid_1 < 0 || msgid_2 < 0){
		perror("msgget");
		return -1;
	}
	printf("msgid_1 = %d\n",msgid_1);
	printf("msgid_2 = %d\n",msgid_2);

	ssize_t res;
	struct msgbuf buf;
	struct msgbuf rcv;

	__sighandler_t res_1 = signal(SIGUSR1,handler);
	if(SIG_ERR == res_1){
		perror("signal");
		return -1;
	}

	pid_t pid = fork();
	if(pid < 0){
		perror("fork");
		return -1;
	}
	if(pid > 0){
		
		while(1){
			res = msgrcv(msgid_2,&rcv,sizeof(rcv.mtext),0,0);

			if(res < 0){
				perror("msgrcv");
				return -1;
			}

			if(strcmp(rcv.mtext,"quit") == 0){
				kill(getpid(),SIGUSR1);
			}
			printf("rcv msg type=%ld text=%s\n",rcv.mtype,rcv.mtext);
		}
	}else{
		while(1){
			buf.mtype = 1;

			scanf("%s",buf.mtext);

			if(msgsnd(msgid_1,&buf,sizeof(buf.mtext),0) < 0){
				perror("msgsnd");
				return -1;
			}
		
			if(strcmp(buf.mtext,"quit") == 0){
				kill(getpid(),SIGUSR1);
			}
		}
	}

	return 0;
}

ubuntu@ubuntu:20230306_ipc$ ./1
key_1=1090588962
key_2=1107366178
msgid_1 = 2
msgid_2 = 3
aaaa
bbbb
cccc
rcv msg type=1 text=dddd
rcv msg type=1 text=eeee
msgid_1=2 deleted
msgid_2=3 deleted

ubuntu@ubuntu:20230306_ipc$ ./2
key_1=1090588962
key_2=1107366178
msgid_1 = 2
msgid_2 = 3
rcv msg type=1 text=aaaa
rcv msg type=1 text=bbbb
rcv msg type=1 text=cccc
dddd
eeee
quit
msgrcv: Identifier removed
msgctl: Invalid argument
msgctl: Invalid argument

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值