实验报告linux进程同步与互斥,实验五 Linux的进程管理-同步和互斥

实验目的:

通过实验掌握下列知识:

1、熟悉wait()系统调用,getpid()系统调用,getppid()系统调用。

2、掌握在Linux下,利用Exec函数族完成其他程序的调用。

3、熟悉在Linux环境下,利用lockf()系统调用完成临界区的互斥。

内容及步骤:

一、

进程创建等待

(1)进程等待

对fork1程序进行修改,让父进程等待并检查子进程的退出状态。Wait.c

子进程的结束状态返回后存于status,下面有几个宏可判别结束情况:

WIFEXITED(status)如果子进程正常结束则为非0

值。

WEXITSTATUS(status)取得子进程exit()返回的结束代码,一般会先用WIFEXITED 来判断是否正常结束才能使用此宏。

WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真。

WTERMSIG(status)

取得子进程因信号而中止的信号代码,一般会先用WIFSIGNALED

来判断后才使用此宏。

WIFSTOPPED(status)

如果子进程处于暂停执行情况则此宏值为真。一般只有使用WUNTRACED

时才会有此情况。

WSTOPSIG(status)

取得引发子进程暂停的信号代码,一般会先用WIFSTOPPED

来判断后才使用此宏。

#include

#include

#include

#include

int main ()

{

pid_t pid;

char

*message;

int n;

int

exit_code;

printf(“fork program

starting\n”);

pid=fork();

switch(pid)

{

case -1:

perror(“fork failed!\n”);

exit(1);

case 0:

message=”This is the child”;

n=5;

exit_code=37;

break;

default:

message=”This is the

parent”;

n=3;

exit_code=0;

break;

}

for(;n>0;n--)

{

puts(message);

sleep(1);

}

if(pid!=0)

{

int stat_val;

pid_t child_pid;

child_pid =

wait(&stat_val);

printf(“Child has finished: PID = %d\n”,

child_pid);

if(WIFEXITED(stat_val))

printf(“Child exited with code %d\n”,

WEXITSTATUS(stat_val));

else

printf(“Child terminated

abnormally\n”);

}

exit(exit_code);

}

二、

获取进程ID号

getpid()和getppid(),取得目前进程的识别码(进程ID),许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。系统调用格式:int

getpid(),getppid()取得目前进程的父进程识别码。

(2)利用getpid()函数和gteppid()函数获取当前子进程和父进程的Pid号。

#include

#include

Int p1,p2;

int main ()

{

P1=fork();

If(p1==0)

Printf(“child 1

%d\n”,getpid());

Else{

P2=fork();

If(p2==0)

Printf(“child 2

%d\n”,getpid());

Else

Printf(“parent

%d\n”,getppid());

}

}

三、

利用Exec函数族调用程序

(3)exec系统调用

#include

int execl(const char *path,

const char *arg, ...);

int execlp(const char *file,

const char *arg, ...);

int execle(const char *path,

const char *arg, ..., char *const envp[]);

int execv(const char *path,

char *const argv[]);

int execvp(const char *file,

char *const argv[]);

int execve(const char *path,

char *const argv[], char *const envp[]);

在以上六个exec函数中,第一个参数如果为pathname,说明被执行程序是由路径名指定,如果为filename,则说明是由文件名指定;第二个参数如果为数组,说明被执行程序的参数是由一个数组来索引(数组必须含有一个空指针来表示结束),否则需要将参数一一列出;execle()及execve()的envp指针数组表示这两个函数显示指定一个环境表(这个数组必须以一个空指针结束),而另外四个函数则用外部变量environ的当前值来创建一个环境表传递给新程序。

int execl(const char*

fullpath, const char* arg, ....)

使用范例:execl(“/bin/ls”,

”ls”,

”-al”,

NULL)

int execlp(const char* file,

const char* arg, ....)

使用范例:execlp(“ls”,

”ls”,

”-al”,

NULL)

int execle(const char*

fullpath, const char* arg, ...., char* const

envp[])

使用范例:execle(“/bin/ls”,

”ls”,

”-al”, NULL,

environ)

int execv(const char *

fullpath, char* const argv[])

使用范例:execle(“/bin/mkdir”, argv) // int main(int argc,

char* argv[])

char* const p[] = {"a.out",

"testDir", NULL};

execv("/bin/mkdir",

p);

int execvp(const char* file,

const char* arg, ....)

使用范例:execlp(“ls”, argv) // int main(int argc,

char* argv[])

char* const p[] = {"a.out",

"testDir", NULL};

execvp("mkdir",

p);

int execve(const char*

fullpath, const char* arg, ...., char* const

envp[])

使用范例:execve(“/bin/ls”, argv,

environ)

char* const p[] = {"a.out",

"testDir", NULL};

execve("/bin/mkdir",

p);

利用execlp函数显示当前目录下的文件。

#include

#include

#include

#include

int main()

{

pid_t pid1;

pid1=fork();

if(pid1<0)

{fprintf(stderr,"Fork failed!\n");exit(-1);}

else if(pid1==0) {

execl("/bin/ls","ls","-al","/root/4/",NULL);}

else

{wait(NULL);

printf("child

complete!\n");

exit(0);}

return 0;

}

四、

进程互斥lockf( )系统调用

(4)如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。

Lockf(1,1,0)是给屏幕上锁,lockf(1,0,0)是给屏幕解锁。

#include

#include

#include

#include

int p1,p2;

int main()

{

p1=fork();

if(p1==0)

{

for(i=0;i<15;i++)

{

printf("child1

%d\n",i);

sleep(2);

}

}

else

{

p2=fork();

if(p2==0)

{

lockf(1,1,0);

for(i=0;i<15;i++)

{

printf("child2

%d\n",i);

sleep(1);

}

lockf(1,0,0);

}

else

{

lockf(1,1,0);

for(i=0;i<15;i++)

printf("parent

%d\n",i);

lockf(1,0,0);

}

}

在程序中,会出现交替进程运行的情况。

(5)通过文件locked.txt资源,实现进程互斥。

#include

#include

#include

#include

int main()

{

int p1,p2,i;

FILE* fp;

fp =

fopen("locked.txt","w+");

if(fp==NULL)

{

printf("Failed to create

file");

exit(-1);

}

while

((p1=fork())==-1);

if(p1==0)

{

lockf(fp,1,0);

for(i=0;i<10;i++)

fprintf(fp,"child1 is

%d\n",i);

lockf(fp,0,0);

}

else

{

while((p2=fork())==-1);

if(p2==0)

{

lockf(fp,1,0);

for(i=0;i<10;i++)

fprintf(fp,"child2 is

%d\n",i);

lockf(fp,0,0);

}

else

{

wait(NULL);

lockf(fp,1,0);

for(i=0;i<10;i++)

fprintf(fp, "parent is

%d\n",i);

lockf(fp,0,0);

}

}

fclose(fp);

}

./lockfile,运行,结果通过cat

locked.txt运行。

你可能感兴趣的:(实验报告linux进程同步与互斥,实验五 Linux的进程管理-同步和互斥)