进程控制题

如题

 

 

 

 

解析:这道题的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%

posted @ 2019-11-19 22:34  C_hp  阅读(177)  评论(0)    收藏  举报