【问题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 usevarious 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
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
}
}
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);
}