进程控制题
如题

解析:这道题的1,3问比较简单,就不多做介绍,主要是第2问。拿到这道题后我立马就想到了可以用进程间通信解决,回忆了一下,感觉明明学过,但是不知从何下手,因此,第一版代码用的时间差来控制进程的写入。
代码如下
#include<stdlib.h>
#include<time.h>
#include<error.h>
#include<errno.h>
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
int get_second()
{
time_t timer;
struct tm *tblock;
time(&timer);
tblock = gmtime(&timer);
return (int)(tblock->tm_sec);
}
int init()
{
FILE *fd1, *fd2, *fd3;
fd1 = fopen("a.cfg", "w");
if(fd1 == NULL)
{
printf(" init open file error!\n");
exit(1);
}
fclose(fd1);
fd1 = fopen("c.cfg", "w");
if(fd1 == NULL)
{
printf(" init open file error!\n");
exit(1);
}
fputs("helloworld", fd1);
fclose(fd1);
fd2 = fopen("b.cfg", "w");
if(fd2 == NULL)
{
printf("init open file error!\n");
exit(1);
}
fputs("0123456789", fd2);
fclose(fd2);
}
int Fgets(const char *file, char *str)
{
FILE *fd1;
fd1 = fopen(file, "r+");
if(fd1 == NULL)
{
printf("open file error!\n");
exit(1);
}
fgets(str, 11, fd1);
fclose(fd1);
}
int Write(int i, char *p)
{
FILE *fd1;
fd1 = fopen("a.cfg", "a");
if(fd1 == NULL)
{
printf("open file error!\n");
exit(1);
}
fputc(p[i], fd1);
fclose(fd1);
}
int main()
{
pid_t pid, pid1, pid2;
int stat = 0, i = 0;
char p[11] = {0};
char *ar[] = {"vi", "a.cfg", NULL};
init();//ques1
pid1 = fork();
if(pid1 == 0)//ques2
{
Fgets("b.cfg", p);
p[10] = '\0';
while(i<10)
{
if(get_second()%2 == 1)
{
Write(i, p);
++i;
}
sleep(1);
}
exit(0);
}
else
{
pid2 = fork();
if(pid2 == 0)//ques2
{
Fgets("c.cfg", p);
p[10] = '\0';
sleep(1);
while(i<10)
{
if(get_second()%2 == 0)
{
Write(i, p);
++i;
}
sleep(1);
}
}
else
{
printf("parent process PID is %ld, P1 process PID is %d, P2 process PID is %d\n", getpid(), pid1, pid2);
waitpid(pid2, NULL, NULL);
}
}
if(pid2 == 0)//ques3
{
errno = 0;
printf("process %d will use vi open file %s\n", getpid(), "a.cfg");
if(execl("/usr/bin/vi", "vi", "/home/mr_han/code/exp/process/a.cfg")<0)
printf("error num is %d, reason is %s\n", errno, strerror(errno));;
}
exit(0);
}
3个进程启动后,让P2进程先睡眠一秒,以保证P1进程先写入。P1进程仅在奇数秒写入,P2进程仅在偶数秒写入,两个进程交替写共至少需要20秒。(着实很蠢的办法)
接着回去再看了看管道通信的部分,考虑使用两个无名管道进行相互通知自己已经写到a文件结束,这样就不用休眠,大大降低程序的执行时间。
#include<stdlib.h>
#include<time.h>
#include<error.h>
#include<errno.h>
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
int init()
{
FILE *fd1, *fd2, *fd3;
fd1 = fopen("a.cfg", "w");
if(fd1 == NULL)
{
printf(" init open file error!\n");
exit(1);
}
fclose(fd1);
fd1 = fopen("c.cfg", "w");
if(fd1 == NULL)
{
printf(" init open file error!\n");
exit(1);
}
fputs("helloworld", fd1);
fclose(fd1);
fd2 = fopen("b.cfg", "w");
if(fd2 == NULL)
{
printf("init open file error!\n");
exit(1);
}
fputs("0123456789", fd2);
fclose(fd2);
}
int read_from_pipe(int fd)
{
char message[100] = {0};
if(read(fd, message, 100) > 0)
{
// printf("read from pipe:%s\n", message);
return 1;
}
else
return 0;
}
int write_to_pipe(int fd)
{
char *message = "Linux is a nice system!\n";
if(write(fd, message, strlen(message)+1) == -1)
{
printf("write error!\n");
exit(1);
}
return 1;
}
int Fgets(const char *file, char *str)
{
FILE *fd1;
fd1 = fopen(file, "r+");
if(fd1 == NULL)
{
printf("open file error!\n");
exit(1);
}
fgets(str, 11, fd1);
fclose(fd1);
}
int Write(int i, char *p)
{
FILE *fd1;
fd1 = fopen("a.cfg", "a");
if(fd1 == NULL)
{
printf("open file error!\n");
exit(1);
}
fputc(p[i], fd1);
fclose(fd1);
}
int main()
{
pid_t pid, pid1, pid2;
int stat = 0, i = 0, fd[2], fd1[2];
char p[11] = {0};
char *ar[] = {"vi", "a.cfg", NULL};
init();
if(pipe(fd) || pipe(fd1))
{
perror("Create pipe failed!\n");
exit(1);
}
pid1 = fork();
if(pid1 == 0)
{
Fgets("b.cfg", p);
p[10] = '\0';
do
{
Write(i, p);
++i;
close(fd[0]);
close(fd1[1]);
printf("P1 running\n");
write_to_pipe(fd[1]);//告诉P2进程P1进程已经写结束
}while(i<10 && read_from_pipe(fd1[0]));
exit(0);
}
else
{
pid2 = fork();
if(pid2 == 0)
{
Fgets("c.cfg", p);
p[10] = '\0';
//sleep(1);
close(fd[1]);
while(i<10 && read_from_pipe(fd[0]))
{
Write(i, p);
++i;
close(fd1[0]);
write_to_pipe(fd1[1]);//告诉P1进程P2已经写结束
printf("P2 running\n");
close(fd[1]);
}
}
else
{
printf("parent process PID is %ld, P1 process PID is %d, P2 process PID is %d\n", getpid(), pid1, pid2);
waitpid(pid2, NULL, NULL);
}
}
if(pid2 == 0)
{
errno = 0;
printf("process %d will use vi open file %s\n", getpid(), "a.cfg");
if(execl("/usr/bin/vi", "vi", "/home/mr_han/code/exp/process/a.cfg")<0)
printf("error num is %d, reason is %s\n", errno, strerror(errno));
}
exit(0);
}
这版的时间不到1秒,效率增加接近2000%
不积小流无以成江河

浙公网安备 33010602011771号