作业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