歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> Linux基礎練習_進程

Linux基礎練習_進程

日期:2017/3/3 13:47:57   编辑:Linux技術

【問題1】

Write a C program that creates a new process to copy the files using the sample

MyCopy. This program should spawn a new process using fork system call. Then use

execlp to execute MyCopy program. The source and destination file names presented

as command-line arguments should be passed to execlp as system call arguments. The

main process waits for completion of copy operation using wait system call. Use

various system calls for time to calculate the execute time of this program.

【解答】

MyCopy.c

#include "header.h"

int main(int argc, char* argv[ ]){
	if(argc!=3){      // parameter error
        printf("Wrong Usage: MyCopy <source file name> <target file name>\n");
		exit(-1);
    }

	FILE *src;
	clock_t start,end;     // the beginning and the end of the time
	double elapsed;     // period of time

	struct timeval startTime, endTime;
    struct timezone tz;
    long run_time_in_microseconds;

	start = clock();        //time count
	gettimeofday(&startTime, &tz);
	src = fopen(argv[1],"r");        //Open source file
	//Check for file error
	if(src==NULL){
		printf("Error: Could not open file '%s'.\n",argv[1]);
		exit(-1);
	}

    FILE *dest;
	dest = fopen(argv[2],"w+");       //Open destination file
	//Check for file error
	if(dest==NULL){
		printf("Error:Could not open file '%s'.\n",argv[2]);
		fclose(src);
		exit(-1);
	}

	char c;
	//copy use fgetc fputc
	while(!feof(src)){
		c = fgetc(src);
		if(!feof(src)) fputc(c,dest);
	}
	fclose(src);
	fclose(dest);

	end = clock();
	gettimeofday(&endTime, &tz);

	elapsed = ((double)(end-start))/CLOCKS_PER_SEC*1000;     // time in millisecond
	printf("MyCopy Time used:%f millisecond\n",elapsed);

	run_time_in_microseconds = endTime.tv_usec - startTime.tv_usec;
	printf("Time used: %ld microseconds.\n",run_time_in_microseconds);

	exit(0);
}
ForkCopy.c
#include "header.h"

int main(int argc, char *argv[ ])
{
    pid_t ForkPID;
    ForkPID = fork();         // Using system call "fork" to create a new process

    if (ForkPID>0){           // parent process
        int status = 0;
   		wait(&status);
   		exit(0);
    }else if (ForkPID==0){     // child process
        execlp("./MyCopy", argv[0], argv[1], argv[2], NULL);
    }else{      // fail to fork a child process
        printf("Error: Failed to fork.\n");
        exit(-1);
    }
}

【問題2】

Make the mini shell (from the sample MyShell) a little more powerful by allowing

arguments to the commands. For example, it should be able to execute commands

such as more filename and ls -l ~/tmp etc.

【解答】

MoreShell.c

#include "header.h"

int main(int argc, char* argv[ ]){
	if(argc!=1){
		printf("Wrong Usage: MyShell\n");
		exit(-1);
	}  //To start the mini-shell, you should call ./MoreShell

	printf("PID:%d, MyShell (\"exit\" for end) >>", getpid()); //wait for the user to input some commands

	char *buffer=NULL;   size_t len=0;
	while (1){
            getline(&buffer, &len, stdin);  //read the whole line
            buffer[strlen(buffer)-1]='\0';  //replace the character '\n' by '\0' to indicate the end of the command buffer

            if (!strcmp(buffer, "exit")) { free(buffer); break; } //if user's command is 'exit', the mini-shell is terminated.

            char **argvs = (char **) malloc (sizeof(char *)); //ready to receive arguments of the command(seperated by whitespace)
            int count=0; //number of arguments

            //seperate the command using the way proposed by ppt
            char *p=strtok(buffer, " ");
            while (p!=NULL && strcmp(p,"|")!=0) {
                    argvs[count]=p;
                    count ++;
                    argvs = realloc(argvs, (count+1) * sizeof(char *));
                    p = strtok(NULL," ");
            }
            argvs[count]=NULL;  //the last argument should be 'NULL'

            pid_t ForkPID=fork(); //use system call 'fork' to create a new process for executing the given command
            int status;

            switch(ForkPID){
                case -1:       //failed to create the child process
                    printf("Error:Failed to fork.\n");  break;
                case 0:   //child process, first executes the given command then receives the status
                    if (execvp(argvs[0],argvs)==-1) printf("Error: running command: '%s'\n", argvs[0]);
				    exit(0);
				    break;
                default:  //parent process, waiting for child process to be finished
                    wait(&status);
            }

            printf("PID:%d, MyShell (\"exit\" for end) >>", getpid()); //waiting for the user to input next command
	}
}
【問題3】

Modify the sample MyThread using two semaphores to control the program then

let thread 1 modify number before thread 2.

【解答】

MoreThread.c

#include "header.h"

int number;//protected external value

sem_t    sem_id1,  sem_id2;

//thread 1
void *thread_one_fun(void*argv){
	sem_wait(&sem_id1);  //get the acces to number
	printf("Thread 1 is going to change the number.\n");
	number++;
	printf("Thread 1: number = %d \n",number);
	sem_post(&sem_id2); //let thread two go after thread one has finished
    pthread_exit(NULL);
}

//thread 2
void *thread_two_fun(void*argv){
	sem_wait(&sem_id2);  //if thread two executes first, it will be blocked for sem_id2 is 0 at the beginning.
	printf("Thread 2 is going to change the number.\n");
	number--;
	printf("Thread 2: number = %d \n",number);
	sem_post(&sem_id1);  //after thread two has finished, post sem_id1
    pthread_exit(NULL);
}

int main(int argc, char* argv[]){
	number = 1;
	printf("main function: number=1 at the beginning.\n");

	sem_init(&sem_id1,0,1); //initialize sem_id1 to be 1
	sem_init(&sem_id2,0,0); //initialize sem_id2 to be 0

	pthread_t     pt1,pt2;
	int id[2];    id[0] = 1;   id[1] = 2;

    int rc;
	rc=pthread_create(&pt1,NULL,thread_one_fun,&id[0]);
    rc=pthread_create(&pt2,NULL,thread_two_fun,&id[1]);

	void* status1;
	rc = pthread_join (pt1, &status1);
    if (rc) printf("ERROR: return code from pthread_join(pt1) is %d\n", rc);

    void* status2;
	rc = pthread_join (pt2, &status2);
    if (rc) printf("ERROR: return code from pthread_join(pt2) is %d\n", rc);

	sem_destroy(&sem_id1);
	sem_destroy(&sem_id2);

	printf("main function terminated.\n");
	exit(0);
}
【測試結果】

Copyright © Linux教程網 All Rights Reserved