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);
}


【测试结果】




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,以下是关于Linux基础命令练习的回复: Linux基础命令练习是学习Linux操作系统的重要一步。通过练习,可以掌握Linux系统的基本操作,如文件管理、进程管理、用户管理等。这些命令包括ls、cd、mkdir、rm、cp、mv、ps、kill、useradd等等。掌握这些命令可以提高我们在Linux系统上的工作效率,也可以为我们后续的学习打下坚实的基础。因此,我们应该认真学习和练习这些命令,以便更好地应对工作和学习中的挑战。 ### 回答2: Linux是一种广泛使用的服务器操作系统,同时也是开源软件,因此有很多命令可供操作。下面我将简要介绍几个基础命令: 1. ls命令 ls命令是列出目录或文件的命令。它的常见用法是用来查看当前目录下的文件,也可以在命令中指定目录名,例如: ls /home/username 2. cd命令 cd命令是用来改变目录的命令。它的常见用法是用来进入某个目录,也可以使用相对路径或绝对路径来到达目标目录,例如: cd /home/username/Downloads 3. mkdir命令 mkdir命令是用来创建目录的命令。它的语法为: mkdir [-p] directory 其中,-p选项可以创建目录路径中缺失的父目录。 4. rm命令 rm命令是用来删除文件或目录的命令。它的语法为: rm [-r] filename 其中,-r选项可以递归删除目录及其子目录。 5. cp命令 cp命令是用来复制文件或目录的命令。它的语法为: cp [-r] source_file destination 其中,-r选项可以递归复制目录及其子目录。 6. mv命令 mv命令是用来移动或重命名文件或目录的命令。它的语法为: mv source_file destination 其中,如果destination是一个目录名,则将source_file移动到目录中;如果destination是文件名,则将source_file重命名为目标文件名。 以上只是Linux基础命令的浅尝辄止,真正灵活使用还需要深入学习,并结合具体场景应用。 ### 回答3: Linux是一个非常流行的操作系统,它具有强大的命令行工具和应用。为了更好地利用Linux操作系统,程序员需要对Linux终端命令非常熟悉。 下面,我将回答一些常见的Linux基础命令练习。 1. 怎样进入Linux终端? 打开终端应用,键入用户名和密码即可进入Linux终端。 2. 如何查看当前目录的内容? 使用“ls”命令,这将列出当前目录中的所有文件和子目录。 3. 如何创建一个新目录? 使用“mkdir”命令,例如“mkdir test”将创建一个名为“test”的新目录。 4. 如何将文件从一个目录移动到另一个目录? 使用“mv”命令并指定原始文件的路径和目标目录的路径,例如“mv /home/user/myfile.txt /home/user/documents/”将将“myfile.txt”移动到“documents”目录中。 5. 如何将一个目录中的所有文件复制到另一个目录中? 使用“cp”命令并指定原始目录和目标目录,例如“cp /home/user/documents/* /home/user/backups/”将复制“documents”目录中的所有文件到“backups”目录中。 6. 如何删除一个文件? 使用“rm”命令并指定要删除的文件名,例如“rm myfile.txt”。 7. 如何删除一个目录? 使用“rmdir”命令并指定要删除的目录名,例如“rmdir test”。 8. 如何查看一个文件的内容? 使用“cat”命令并指定要查看的文件名,例如“cat myfile.txt”。 9. 如何在终端中直接编辑一个文件? 使用“nano”或“vi”命令,例如“nano myfile.txt”。 10. 如何查看当前进程? 使用“ps”命令,这将列出当前正在运行的所有进程。 以上是常见的Linux基础命令,对于Linux的进一步运用,程序员还需要了解更高级的命令和技巧。熟悉这些命令和技巧有助于程序员更高效地使用Linux并提高工作效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值