#include "sys/types.h" #include "sys/file.h" #include "unistd.h" char r_buf[4]; //读缓冲 char w_buf[4]; //写缓冲 int pipe_fd[2]; pid_t pid1, pid2, pid3, pid4; int producer(int id); int consumer(int id); int main(int argc,char **argv){ if(pipe(pipe_fd)<0){//传输出错 printf("pipe create error \n"); exit(-1); } else{ printf("pipe is created successfully!\n"); //谁占用管道谁进行数据传输 if((pid1=fork())==0) producer(1); if((pid2=fork())==0) producer(2); if((pid3=fork())==0) consumer(1); if((pid4=fork())==0) consumer(2); } close(pipe_fd[0]); //需要加上这两句 close(pipe_fd[1]); //否者会有读者或者写者永远等待 int i,pid,status; for(i=0;i<4;i++) pid=wait(&status); //返回子进程状态 exit(0); } //生产者 int producer(int id){ printf("producer %d is running!\n",id); close(pipe_fd[0]); int i=0; for(i=1;i<10;i++){ sleep(3); if(id==1) //生产者1 strcpy(w_buf,"aaa\0"); else //生产者2 strcpy(w_buf,"bbb\0"); if(write(pipe_fd[1],w_buf,4)==-1) printf("write to pipe error\n"); } close(pipe_fd[1]); printf("producer %d is over!\n",id); exit(id); } //消费者 int consumer(int id){ close(pipe_fd[1]); printf(" producer %d is running!\n",id); if (id==1) //消费者1 strcpy(w_buf,"ccc\0"); else //消费者2 strcpy(w_buf,"ddd\0"); while(1){ sleep(1); strcpy(r_buf,"eee\0"); if(read(pipe_fd[0],r_buf,4)==0) break; printf("consumer %d get %s, while the w_buf is %s\n",id,r_buf,w_buf); } close(pipe_fd[0]); printf("consumer %d is over!\n", id); exit(id); }3.参考代码producer()和consumer()中的sleep的作用
时间: 2023-07-14 08:14:24 浏览: 29
在这个代码中,生产者和消费者都使用了 sleep 函数来模拟一些实际情况下需要等待的操作。具体来说,生产者在每次循环中会等待 3 秒钟,以模拟生产过程中的一些耗时操作。而消费者则是在每次循环中等待 1 秒钟,以模拟消费者执行某些操作需要的时间。这样做可以更加接近实际情况,也能够更好地展示管道的使用方式。
相关问题
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <pwd.h> #include <grp.h> #include <time.h> void shell_ls_l(char *file,struct stat st) { char limi
ted[11]; // 文件权限 mode_t mode = st.st_mode; limitted[0] = (S_ISDIR(mode)) ? "d" : "-"; limitted[1] = (mode & S_IRUSR) ? "r" : "-"; limitted[2] = (mode & S_IWUSR) ? "w" : "-"; limitted[3] = (mode & S_IXUSR) ? "x" : "-"; limitted[4] = (mode & S_IRGRP) ? "r" : "-"; limitted[5] = (mode & S_IWGRP) ? "w" : "-"; limitted[6] = (mode & S_IXGRP) ? "x" : "-"; limitted[7] = (mode & S_IROTH) ? "r" : "-"; limitted[8] = (mode & S_IWOTH) ? "w" : "-"; limitted[9] = (mode & S_IXOTH) ? "x" : "-"; limitted[10] = '\0'; printf("%s ", limitted); // 链接数、所有者、所在组、文件大小、创建时间、文件名 printf("%ld ", (long)st.st_nlink); printf("%s ", getpwuid(st.st_uid)->pw_name); printf("%s ", getgrgid(st.st_gid)->gr_name); printf("%lld ", (long long)st.st_size); char time_buf[20]; strftime(time_buf, 20, "%b %d %H:%M", localtime(&st.st_ctime)); printf("%s ", time_buf); printf("%s\n", file); } int main(int argc, char *argv[]) { DIR *dir; struct dirent *ptr; struct stat st; char path[256]; if (argc == 1) { getcwd(path, 256); dir = opendir(path); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0] == '.') continue; stat(ptr->d_name, &st); shell_ls_l(ptr->d_name, st); } } else if (argc == 2) { if (strcmp(argv[1], "-l") == 0) { getcwd(path, 256); dir = opendir(path); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0] == '.') continue; stat(ptr->d_name, &st); shell_ls_l(ptr->d_name, st); } } else { dir = opendir(argv[1]); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0] == '.') continue; sprintf(path, "%s/%s", argv[1], ptr->d_name); stat(path, &st); shell_ls_l(ptr->d_name, st); } } } else if (argc == 3) { if (strcmp(argv[1], "-l") == 0) { dir = opendir(argv[2]); while ((ptr = readdir(dir)) != NULL) { if (ptr->d_name[0] == '.') continue; sprintf(path, "%s/%s", argv[2], ptr->d_name); stat(path, &st); shell_ls_l(ptr->d_name, st); } } } return 0; }
这是一个简单的实现Linux命令ls -l的程序,可以列出文件的权限、链接数、所有者、所在组、文件大小、创建时间、文件名等信息。
基于以下代码,分析_exit()与exit()在进程退出时的不同行为,结合行缓冲机制,如果调用_exit()函数结束进程并打印父进程信息,应该怎样操作:#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> int global=22; char buf[]="the test content!\n"; int mai
n() {
int var=88;
pid_t pid;
int fd;
if ((fd=open("testfile",O_CREAT|O_WRONLY|O_TRUNC,0644)) <0) {
perror("open error");
exit(1);
}
if (write(fd,buf,sizeof(buf)-1) != sizeof(buf)-1) {
perror("write error");
exit(1);
}
printf("before fork\n");
if ((pid=fork())<0) {
perror("fork error");
exit(1);
} else if (pid==0) {
global++;
var++;
printf("child changed\n");
printf("global=%d, var=%d\n",global,var);
// exit(0);
_exit(0);
}
if (waitpid(pid,NULL,0)<0) {
perror("waitpid error");
exit(1);
}
printf("parent changed\n");
printf("global=%d, var=%d\n",global,var);
exit(0);
}
1. _exit()与exit()的区别在于_exit()是直接终止进程,而exit()则是先执行一些清理工作(如调用函数库中的清理函数),然后再终止进程。
2. 在本代码中,如果使用_exit()函数结束进程并打印父进程信息,应该在子进程中添加以下代码:
```
printf("parent process id=%d\n", getppid());
_exit(0);
```
这样子进程就会直接终止,同时打印出父进程的进程ID。如果使用exit()函数,则需要在子进程中添加清理函数并调用exit()函数来结束进程。