嵌入式linux实验报告.docx

上传人:b****6 文档编号:6115135 上传时间:2023-01-03 格式:DOCX 页数:24 大小:4.20MB
下载 相关 举报
嵌入式linux实验报告.docx_第1页
第1页 / 共24页
嵌入式linux实验报告.docx_第2页
第2页 / 共24页
嵌入式linux实验报告.docx_第3页
第3页 / 共24页
嵌入式linux实验报告.docx_第4页
第4页 / 共24页
嵌入式linux实验报告.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

嵌入式linux实验报告.docx

《嵌入式linux实验报告.docx》由会员分享,可在线阅读,更多相关《嵌入式linux实验报告.docx(24页珍藏版)》请在冰豆网上搜索。

嵌入式linux实验报告.docx

嵌入式linux实验报告

 

嵌入式操作系统Linux

实验报告

 

专业:

计算机科学与技术

班级:

13419011

学号:

1341901124

姓名:

武易

组员:

朱清宇

 

实验一Linux下进程的创建

一实验目的

1.掌握Linux下进程的创建及退出操作

2.了解fork、execl、wait、waitpid及之间的关系

二实验内容

创建进程,利用fork函数创建子进程,使其调用execl函数,退出进程后调用wait或waitpid清理进程。

三实验过程

1.进程的创建

许多进程可以并发的运行同一程序,这些进程共享内存中程序正文的单一副本,但每个进程有自己的单独的数据和堆栈区。

一个进程可以在任何时刻可以执行新的程序,并且在它的生命周期中可以运行几个程序;又如,只要用户输入一条命令,shell进程就创建一个新进程。

fork函数用于在进程中创建一个新进程,新进程是子进程。

原型如下:

#include /* 提供类型pid_t的定义 */

#include /* 提供函数的定义 */

pid_t fork(void);

使用fork函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间

fork系统调用为父子进程返回不同的值,fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:

✓在父进程中,fork返回新创建子进程的进程ID;

✓在子进程中,fork返回0; 

✓如果出现错误,fork返回一个负值;

用fork创建子进程后执行的是和父进程相同的程序,子进程可以通过调用exec函数以执行另一个程序。

当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程(例如其main函数)开始执行。

调用exec并不创建新进程,进程ID并未改变,只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。

exec函数原型

execl,execlp,execle,execv,execve和execvp

2.进程的退出

一个进程正常终止有三种方式:

由main()函数返回;

调用exit()函数;

调用_exit()或_Exit()函数。

#include

#include

exit:

voidexit(intstatus)

_exit:

void_exit(intstatus)

3.wait和waitpid

一个进程调用了exit之后,该进程并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构。

在Linux进程的5种状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集。

如果一个进程已经终止,但是它的父进程尚未调用wait或waitpid对它进行清理,这时的进程状态称为僵尸(Zombie)进程。

该类进程保留了一定的信息(包括pID,退出状态,运行时间等),需要父进程通过wait/waitpid来取时才释放。

如果父进程不调用wait/waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,如果系统大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程。

父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。

也可以杀死父进程,则Zombie子进程会自动由init进程托管(init会负责清理)。

四实验代码

#include

intmain()

{

inti;

for(i=3;i>0;i--)

{

printf("Thisisthechild\n");

sleep

(2);

}

return0;

}

#include

#include

#include

#include

#include

intmain()

{

pid_tpid,pid_w;

pid=fork();

if(pid<0)

{

perror("forkfailed");

exit

(1);

}

if(pid==0)

{

execl("./chpro","chpro",NULL);

}

else{

do{

pid_w=waitpid(pid,NULL,WNOHANG);

if(pid_w==0){

printf("childprocesshasnoexited\n");

sleep

(1);

}

}while(pid_w==0);

if(pid_w==pid)

printf("Getchild%d\n",pid_w);

else

printf("someerroroccured.\n");

}

return0;

}

五实验结果

 

实验二Linux下shell程序设计

一实验目的

掌握Linux下shell程序的设计方法,脚本文件的编写方法

二实验内容

1.给shell脚本加注释,说明其功能

2.编写一个安装脚本文件,将某个已知的程序安装在/myprogram下

三实验代码

注释shell

#定义两个变量

PREFIX=uptech

TARGETDIR=/arm2410s

clear

#makeneededdirectory

if[-f$TARGETDIR/img/zImage];then

echo"Thetargetdirisalreadyexist!

"

echo"Pleasebackupyourfilesorchangetoanotherdirectory"

exit

fi

mkdir$TARGETDIR2>/dev/null

#初始化arm4l的开发工具

inst_armv4l_gcc(){

echo"installarmv4l-unknown-linux-gcc-2.95.2andlibraray..."

#解包

tar-xjfarmv4l-tools-2.95.2.tar.bz2-C/

}

#安装linux系统及文件系统

inst_linux(){

echo"installlinux-2.4..."

tar-xjf${PREFIX}-kernel.tar.bz2-C$TARGETDIR||exit

echo"installbusybox-1.00-pre10..."

tar-xjf${PREFIX}-busybox-1.00-pre10.tar.bz2-C$TARGETDIR||exit

echo"installrootfs..."

tar-xjf${PREFIX}-root.tar.bz2-C$TARGETDIR||exit

}

#gdb调试器初始化

inst_gdb(){

echo"installgdb&gdbserverforarm920t..."

cp-arfgdb$TARGETDIR||exit

tar-xjfgdb/insight-6.0.tar.bz2-C$TARGETDIR||exit

}

配置exp文件

inst_exp(){

echo"installexamplesprograms..."

cp-arfexp$TARGETDIR||exit

cp-arfdoc$TARGETDIR||exit

}

#初始化GUI程序

inst_gui(){

echo"installguiprograms"

cp-rafmicrowindows$TARGETDIR||exit

mkdir$TARGETDIR/minigui2>/dev/null

tar-jxfminigui/basic.tar.bz2-C$TARGETDIR/minigui

tar-jxfminigui/lib.tar.bz2-C$TARGETDIR/minigui

tar-jxfminigui/mde-1.6.0.tar.bz2-C$TARGETDIR/minigui

tar-jxfminigui/mg-samples-1.6.0.tar.bz2-C$TARGETDIR/minigui

tar-jxfminigui/res-host.tar.bz2-C$TARGETDIR/minigui

tar-jxfminigui/res-target.tar.bz2-C$TARGETDIR/minigui

}

#初始化配置文件

inst_config_file(){

#if[-f/root/.bash_profile];then\#如果/root/.bash_profile文件存在

#echo"backupold.bash_profileto.bash_profile_bak"

#cp-f/root/.bash_profile/root/.bash_profile.bak

#fi

#echo"copy.bash_profileto/root"

#cp-af.bash_profile/root/.bash_profile

if[-f/etc/minirc.dfl];then\#如果/etc/minirc.dfl文件存在

echo"backup/etc/minirc.df1."

cp-f/etc/minirc.dfl/etc/minirc.dfl.bak

fi

echo"copyminirc.df1to/etc"

cp-afminirc.dfl/etc/minirc.dfl

}

#............................

cdarmv4l-tools||exit

inst_armv4l_gcc

cd..

cddevelop||exit

inst_linux

inst_config_file

cd..

cp-arfsh$TARGETDIR

cp-arfimg$TARGETDIR

mkdir$TARGETDIR/demos

cdimg

tarjxfyaffs.tar.bz2-C$TARGETDIR/demos/2>/dev/null

cd..

inst_gdb

inst_exp

cdgui

inst_gui

cd..

cd$TARGETDIR

echoarm-linuxdevelopenviromentforUP-Netarm2410installcompleted!

 

Mysql-5.5.50-linux2.6-x86_64.tar.gz的安装:

#!

/bin/bash

MYSQL_HOME=/myprogram/mysql

#将你的mysql安装程序解压后的文件名设置为MYSQL_DIR,将安装程序(mysql-xxx.tar.gz)放到当前目录

MYSQL_DIR=mysql-5.5.50-linux2.6-x86_64

MYSQL_DIR_OLD=$PWD/${MYSQL_DIR}

MYSQL_DIR_NEW=/myprogram/${MYSQL_DIR}

MYSQL_SOURCE=$MYSQL_DIR_OLD.tar.gz

if[!

-f${MYSQL_SOURCE}]

then

echo"MySQLpackagenotfound!

"

exit1

fi

idmysql>/dev/null2>&1

if[$?

-eq1]

then

#Ifusermysqldoesnotexist,

#deletegroupmysqlfisrtifexists

sed-i'/^mysql/d'/etc/group

echo"Addgroupmysql"

groupaddmysql

echo"Addusermysql"

useradd-gmysqlmysql

fi

echo"UnzipMySQL-5.5.50"

tarzxvf${MYSQL_SOURCE}>/dev/null2>&1

echo"MoveMySQLtotherightplace"

mv${MYSQL_DIR_OLD}${MYSQL_DIR_NEW}

echo"Createmysqllinkage"

ln-s${MYSQL_DIR_NEW}${MYSQL_HOME}

echo"Changemysqldirectorytotherightuserandgroup"

cd$MYSQL_HOME

chown-Rmysql.

cd$MYSQL_HOME

chgrp-Rmysql.

echo"Createmysqlsystemdatabase"

${MYSQL_HOME}/scripts/mysql_install_db--user=mysql>/dev/null

cd$MYSQL_HOME

chown-Rmysqldata

cd$MYSQL_HOME

chown-Rroot.

echo"SetenvironmentPATH"

sed-i'/exportPATH=\/myprogram\/mysql\/bin:

$PATH/d'/etc/profile

echo'exportPATH=/myprogram/mysql/bin:

$PATH'>>/etc/profile

./etc/profile

echo"Setmysqlassystemservice"

cp$MYSQL_HOME/support-files/mysql.server/etc/init.d/mysql

sysv-rc-confmysqlon

/etc/init.d/mysqlstart

echo-n"Pleaseinputpasswordofmysqluserroot:

"

stty-echo

readROOT_PASSWORD

sttyecho

echo

if[-z$ROOT_PASSWORD]

then

echo"ERROR:

Thepasswordisnull!

"

exit1

fi

mysqladmin-urootpassword"$ROOT_PASSWORD"

mysql-uroot-p$ROOT_PASSWORD-e"grantallon*.*toroot@localhostidentifiedby'$ROOT_PASSWORD'"

if[$?

-eq0]

then

echo"Setmysqluserrootpasswordsuccessfully!

"

fi

 

四实验结果

 

实验三Linux下多线程程序设计

一实验目的

了解多线程程序设计的基本原理。

学习pthread库函数的使用。

二实验内容

读懂pthread.c的源代码,熟悉几个重要的PTHREAD库函数的使用。

掌握共享锁和信号量的使用方法。

进入/arm2410cl/exp/basic/02_pthread目录,运行make产生pthread程序,使用NFS方式连接开发主机进行运行实验。

三实验过程

1.多线程程序的优缺点

多线程程序作为一种多任务、并发的工作方式,有以下的优点:

1)提高应用程序响应。

这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(timeconsuming)置于一个新的线程,可以避免这种尴尬的情况。

2)使多CPU系统更加有效。

操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。

3)改善程序结构。

一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。

LIBC中的pthread库提供了大量的API函数,为用户编写应用程序提供支持。

2.实验源代码与结构流程图本实验为著名的生产者-消费者问题模型的实现,主程序中分别启动生产者线程和消费者线程。

生产者线程不断顺序地将0到1000的数字写入共享的循环缓冲区,同时消费者线程不断地从共享的循环缓冲区读取数据。

流程图如图所示:

1、阅读源代码及编译应用程序

进入exp/basic/02_pthread目录,使用vi编辑器或其他编辑器阅读理解源代码。

运行make产生pthread可执行文件,如图所示。

2、下载和调试

运行可执行程序,观察运行结果的正确性。

四实验代码

#include

#include

#include

//#include

#include"pthread.h"

#defineBUFFER_SIZE16

/*设置一个整数的圆形缓冲区*/

structprodcons{

/*缓冲区数组*/

intbuffer[BUFFER_SIZE];

pthread_mutex_tlock;/*互斥锁*/

intreadpos,writepos;/*读写的位置*/

/*缓冲区非空信号*/

pthread_cond_tnotempty;

/*缓冲区非满信号*/

pthread_cond_tnotfull;

};

/*--------------------------------------------------------*/

/*初始化缓冲区*/

voidinit(structprodcons*b)

{

pthread_mutex_init(&b->lock,NULL);

pthread_cond_init(&b->notempty,NULL);

pthread_cond_init(&b->notfull,NULL);

b->readpos=0;

b->writepos=0;

}

/*--------------------------------------------------------*/

/*向缓冲区中写入一个整数*/

voidput(structprodcons*b,intdata)

{

pthread_mutex_lock(&b->lock);

/*等待缓冲区非满*/

while((b->writepos+1)%BUFFER_SIZE==b->readpos){

printf("waitfornotfull\n");

pthread_cond_wait(&b->notfull,&b->lock);

}

/*写数据并且指针前移*/

b->buffer[b->writepos]=data;

b->writepos++;

if(b->writepos>=BUFFER_SIZE)b->writepos=0;

/*设置缓冲区非空信号*/

pthread_cond_signal(&b->notempty);

pthread_mutex_unlock(&b->lock);

}

/*--------------------------------------------------------*/

/*从缓冲区中读出一个整数*/

intget(structprodcons*b)

{

intdata;

pthread_mutex_lock(&b->lock);

/*等待缓冲区非空*/

while(b->writepos==b->readpos){

printf("waitfornotempty\n");

pthread_cond_wait(&b->notempty,&b->lock);

}

/*读数据并且指针前移*/

data=b->buffer[b->readpos];

b->readpos++;

if(b->readpos>=BUFFER_SIZE)b->readpos=0;

/*设置缓冲区非满信号*/

pthread_cond_signal(&b->notfull);

pthread_mutex_unlock(&b->lock);

returndata;

}

/*--------------------------------------------------------*/

#defineOVER(-1)

#defineENDMINITERM27

/*ESCtoquitminiterm*/

structprodconsbuffer;

intstop=0;

intend=0;

/*--------------------------------------------------------*/

void*producer(void*data)

{

intn;

for(n=0;n<1000;n++){

if(stop)

break;

printf("put-->%d\n",n);

put(&buffer,n);

sleep

(1);

}

put(&buffer,OVER);

printf("producerstopped!

\n");

end=1;

returnNULL;

}

/*--------------------------------------------------------*/

void*consumer(void*data)

{

intd;

while

(1){

if(stop)

break;

d=get(&buffer);

if(d==OVER)break;

printf("%d-->get\n",d

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1