为了账号安全,请及时绑定邮箱和手机立即绑定

作业社区

探索学习新天地,共享知识资源!

0 提交作业
0 布置作业
0 满分作业
得分 100
学习任务

慕尼黑0001808 的学生作业:

//在两个进程使用共享内存之间传输文件 #include #include #include #include #include #include #include #include #include #define BAR_WIDTH 50 // 进度条宽度 #define SZ 16 int pipe1[2]; int pipe2[2]; void *shm_addr = NULL; char reveive_file[] = "reveive_"; void my_exit(char str[]){ perror(str); exit(EXIT_FAILURE); } // 打印进度条和百分比 void print_progress(double percentage) { int pos = BAR_WIDTH * percentage; printf("\r["); for (int i = 0; i < BAR_WIDTH; ++i) { if (i < pos) printf("#"); else printf(" "); } printf("] %.2f%%", percentage * 100); fflush(stdout); // 立即刷新输出 } void child_process() { close(pipe1[0]); close(pipe2[1]); int fd = open(reveive_file,O_WRONLY|O_CREAT|O_TRUNC,0666); if(-1 == fd) my_exit("open()"); ssize_t rbytes; while(1){ read(pipe2[0],&rbytes,sizeof(rbytes)); if(0 >= rbytes) break; //printf("读到到共享内存%s\n",(char *)shm_addr); write(fd,shm_addr,rbytes); write(pipe1[1],&rbytes,sizeof(rbytes)); } close(pipe1[1]); close(pipe2[0]); close(fd); } int main(int argc, char *argv[]) { if(2 != argc){ printf("用法:%s \n",argv[0]); exit(EXIT_FAILURE); } strcat(reveive_file,argv[1]); // 获取文件大小(用于进度计算) struct stat st; if (stat(argv[1], &st) == -1) my_exit("stat()"); off_t total_size = st.st_size; off_t transferred = 0; if(-1 == pipe(pipe1)) my_exit("pipe1()"); if(-1 == pipe(pipe2)) my_exit("pipe2()"); key_t key = ftok(".",'m'); int shmid = shmget(key,SZ,IPC_CREAT|0666); shm_addr = shmat(shmid,NULL,0); pid_t c_pid = fork(); if(-1 == c_pid) my_exit("fork()"); if(0 == c_pid){ child_process(); exit(EXIT_SUCCESS); } int fd = open(argv[1],O_RDONLY); ssize_t rbytes; close(pipe1[1]); close(pipe2[0]); if(-1 == fd) my_exit("open()"); while(1){ memset(shm_addr,0,SZ); rbytes = read(fd,shm_addr,SZ); write(pipe2[1],&rbytes,sizeof(rbytes)); if(0 >= rbytes) break; // 更新进度并显示 transferred += rbytes; double progress = (double)transferred / total_size; print_progress(progress); // printf("写入共享内存:%s\n",(char *)shm_addr); read(pipe1[0],&rbytes,sizeof(rbytes)); } close(fd); close(pipe1[0]); close(pipe2[1]); shmctl(shmid,IPC_RMID,NULL); wait(NULL); printf("文件传输完成\n"); return 0; } 运行结果: linux@linux-VMware-Virtual-Platform:~/study/homework/10420$ gcc main.c linux@linux-VMware-Virtual-Platform:~/study/homework/10420$ ./a.out 1.txt [##################################################] 100.00%文件传输完成 linux@linux-VMware-Virtual-Platform:~/study/homework/10420$ diff 1.txt reveive_1.txt linux@linux-VMware-Virtual-Platform:~/study/homework/10420$

得分 100
学习任务

慕尼黑0001808 的学生作业:

//创建两个子进程A与B,父进程分别给两个子进程发型消息,消息类型为 100 与 200 //父进程从键盘循环接收数据,发送给子进程,输入 quit 则退出 #include #include #include #include #include #include #include #include int msgid; int pipe_a[2]; int pipe_b[2]; pid_t pid_a; pid_t pid_b; struct msg_struct { long m_type; char m_text[1024]; }; void signote_handler(int sinno){} void child_process(int msg_type,char child_name) { printf("子进程%c(pid=%d)启动,等待接收消息\n",child_name,getpid()); char flag = '1'; int m_mipe = child_name == 'A' ? pipe_a[1] : pipe_b[1]; struct msg_struct buf; while (1) { write(m_mipe,&flag,1); pause(); if (msgrcv(msgid, &buf, sizeof(buf.m_text), msg_type, 0) == -1) { perror("msgrcv()"); exit(EXIT_FAILURE); } printf("子进程%c(pid=%d)收到类型%d的消息: %s\n",child_name, getpid(), msg_type, buf.m_text); } exit(EXIT_SUCCESS); } void clean_up() { msgctl(msgid, IPC_RMID, NULL); printf("\n消息队列已清理\n"); kill(pid_a,SIGKILL); kill(pid_b,SIGKILL); waitpid(pid_a, NULL, 0); waitpid(pid_b, NULL, 0); } int main() { // 创建消息队列 key_t key = ftok(".", 'm'); if (key == -1) { perror("ftok()"); exit(EXIT_FAILURE); } msgid = msgget(key, IPC_CREAT | 0666); if (msgid == -1) { perror("msgget()"); exit(EXIT_FAILURE); } // 设置信号处理 signal(SIGINT, clean_up); signal(SIGUSR1,signote_handler); // 创建无名管道 if(-1 == pipe(pipe_a)){ perror("Apipe()"); exit(EXIT_FAILURE); } if(-1 == pipe(pipe_b)){ perror("Bpipe()"); exit(EXIT_FAILURE); } // 清屏并设置初始界面 printf("父进程(pid=%d)启动,输入消息内容(输入'quit'退出):\n", getpid()); // 创建子进程A pid_a = fork(); if (pid_a == -1) { perror("fork A failed"); exit(EXIT_FAILURE); } else if (pid_a == 0) { close(pipe_a[0]); child_process(100,'A'); } // 创建子进程B pid_b = fork(); if (pid_b == -1) { perror("fork B failed"); exit(EXIT_FAILURE); } else if (pid_b == 0) { close(pipe_b[0]); child_process(200,'B'); } struct msg_struct buf; char flag; // 主循环 while (1) { read(pipe_a[0],&flag,1); read(pipe_b[0],&flag,1); printf("> "); // 读取输入 if (fgets(buf.m_text, sizeof(buf.m_text), stdin) == NULL) { perror("fgets()"); break; } // 处理换行符 buf.m_text[strcspn(buf.m_text, "\n")] = '\0'; // 检查退出条件 if (strcmp(buf.m_text, "quit") == 0) { break; } // 发送消息给A buf.m_type = 100; if (msgsnd(msgid, &buf, strlen(buf.m_text)+1, 0) == -1) { perror("msgsnd to A failed"); break; } // 发送消息给B buf.m_type = 200; if (msgsnd(msgid, &buf, strlen(buf.m_text)+1, 0) == -1) { perror("msgsnd to B failed"); break; } printf("父进程(pid=%d)发送消息成功: %s\n", getpid(), buf.m_text); kill(pid_a,SIGUSR1); kill(pid_b,SIGUSR1); } // 清理资源 clean_up(); printf("父进程(pid=%d)正常退出\n", getpid()); return 0; } 运行结果: linux@linux-VMware-Virtual-Platform:~/study/homework/10416$ ./a.out 父进程(pid=102869)启动,输入消息内容(输入'quit'退出): 子进程A(pid=102870)启动,等待接收消息 子进程B(pid=102871)启动,等待接收消息 > hello 父进程(pid=102869)发送消息成功: hello 子进程A(pid=102870)收到类型100的消息: hello 子进程B(pid=102871)收到类型200的消息: hello > quit 消息队列已清理 父进程(pid=102869)正常退出 linux@linux-VMware-Virtual-Platform:~/study/homework/10416$ ./a.out 父进程(pid=102877)启动,输入消息内容(输入'quit'退出): 子进程A(pid=102878)启动,等待接收消息 子进程B(pid=102879)启动,等待接收消息 > ^C 消息队列已清理 已杀死 linux@linux-VMware-Virtual-Platform:~/study/homework/10416$

得分 100
学习任务

慕尼黑0001808 的学生作业:

//探测用户是否已经输入,如果用户在3秒内没有输入则提示超时一次,如果超时三次程序自动结束。 #include #include #include #include #include #define TIMEOUT_SECOUNTS 3 #define MAX_TIMEOUTS 3 int timeout_count = 0; int input_reveived = 0; void timeout_handler(int signo) { timeout_count++; printf("\n超时,当前超时%d次\n",timeout_count); if(timeout_count >= MAX_TIMEOUTS){ printf("已超时%d次,父进程(pid=%d)超时退出\n",timeout_count,getpid()); exit(EXIT_SUCCESS); } input_reveived = 0; } void input_handler(int signo) { input_reveived = 1; } int main(int argc, char *argv[]) { char buffer[1024] = {0}; pid_t c_pid; signal(SIGALRM,timeout_handler); signal(SIGUSR1,input_handler); while(1){ printf("请在%d秒内尽快完成输入:",MAX_TIMEOUTS); fflush(stdout); c_pid = fork(); if(-1 == c_pid){ perror("[ERROR]fork():"); exit(EXIT_FAILURE); } if(0 == c_pid){ if(fgets(buffer,sizeof(buffer),stdin) != NULL){ printf("你输入的是:%s",buffer); kill(getppid(),SIGUSR1); } exit(EXIT_SUCCESS); } alarm(TIMEOUT_SECOUNTS); pause(); alarm(0); kill(c_pid,SIGKILL); wait(NULL); if(1 == input_reveived){ break; } } printf("父进程(pid=%d正常退出\n)",getpid()); return 0; } 运行结果: linux@linux-VMware-Virtual-Platform:~/study/homework/10412$ gcc main.c linux@linux-VMware-Virtual-Platform:~/study/homework/10412$ ./a.out 请在3秒内尽快完成输入: 超时,当前超时1次 请在3秒内尽快完成输入: 超时,当前超时2次 请在3秒内尽快完成输入: 超时,当前超时3次 已超时3次,父进程(pid=76111)超时退出 linux@linux-VMware-Virtual-Platform:~/study/homework/10412$ ./a.out 请在3秒内尽快完成输入:hello 你输入的是:hello 父进程(pid=76121正常退出 )linux@linux-VMware-Virtual-Platform:~/study/homework/10412$ ./a.out 请在3秒内尽快完成输入: 超时,当前超时1次 请在3秒内尽快完成输入:hello 你输入的是:hello 父进程(pid=76124正常退出 )linux@linux-VMware-Virtual-Platform:~/study/homework/10412$

微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号