嵌入式学习——周总结

学习目标:

  • 掌握进程、线程。
  • 学习网络编程。

学习内容:

  • 进程
    • 1.进程的基本知识。
    • 2.进程的相关命令:1.pstree 2.ps 3.kill 4.bg 5.fg 。
    • 3.虚拟地址与物理地址的概念。
    • 4.fork函数,在当前进程中创建一个子进程。
    • 5.常用的退出进程指令:1.return 2.exit 3._exit
    • 6.收回僵尸态。
  • 线程
    • 1.阻塞与轮询。
    • 2.守护进程Daemon的创建。
    • 3.进程间的通讯方式。
    • 4.线程的由来、线程的概念。
    • 5.线程的创建(函数)。
    • 6.线程的终止(函数)。
    • 7.等待线程退出(函数)。
    • 8.创建分离式线程(函数)。
    • 9.取消线程(函数)。
    • 10.信号量。
    • 11.互斥锁。
    • 12.条件变量。
  • 进程通信之管道通信
    • 1.无名管道通信。
    • 2.有名管道通信。
  • 进程之间的通信
    • 1.进程之间的七大通信方式。
    • 2.信号(产生--发送--处理&注销)。
    • 3.信号发送函数kill。
    • 4.定时闹钟与挂起函数。
    • 5.静态库与动态库。
    • 6.共享内存(创建--映射--撤销--删除)。
    • 7.消息队列(创建--发送--接收--删除)。
  • 网络编程
    • 1.OSI参考模型。
    • 2.IP、端口号、等参数名称。
    • 3.交换机(2层)与路由器(3层)。
    • 4.软件(协议,层次结构(传输层:TCP//UDP)、数据收发过程)。
    • 5.得到网络字节序的函数-大端模式-(inet_addr\htons)。
    • 6.得到主机字节序的函数(int_ntoa、ntohs、atoi)。
    • 7.UPT的服务器和客户端创建。


学习重点:

一    >>>>>fork函数创建子进程:

       子进程创建的过程:拷贝父进程的堆,栈,rodata段,data段,bss段,<3>fork之后父,子进程谁先执行是不确定,取决系统的调度算法
       fork之后,父子进程都是从fork下一条语句开始执行
       fork之后,父子进程拥有独立的4G虚拟地址空间。互相不影响
       fork之后,子进程会继承父进程的打开的文件描述符集合,共享文件状态标志位和文件的偏移量。

二   >>>>>创建守护进程DAEMON:

创建子进程,父进程退出:
       fork()exit();
在子进程中创建的新会话[脱离控制终端]:
       setsid();
改变进程的工作目录到根目录:
       chdir("");
重设文件掩码:
       umask(O);
关掉不需要的文件描述符号:
close(0)close(1)close(2);

三   >>>>>线程与进程
       进程只能在一个时刻干一件事,如果想同时干两件事或多件事,进程就无能为力了。
       进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。允许某些线程共享一部分进程的资源。一个程序的多个执行线路我们称之为线程。它也被称为轻量级别的进程。它是程序执行的最小单元。多个线程共享同一个进程的地址空间,参与系统的统一的调度。一个程序至少有一个进程,一个进程至少有一个线程。既然多个线程共享进程的地址空间。那么这个线程肯定是在进程中创建的。 

四     >>>>>管理线程的函数

     1、互斥锁mutex
为了实现线程间的互斥,必须在同一个线程中pthread_mutex_lock和pthread_mutex_unlock;互斥的意思是,不能同时发生,但发生的先后顺序不在乎。
     2、条件变量cond
为了实现同步,同步首先是“互斥”的,同时又care先后顺序。假如一个线程获取锁之后,还要等某个条件发生(比如:sum>100),如果只用mutex,则线程大部分时间只是在lock和unlock,并且要sleep一段时间,短了浪费CPU,长了会拉长响应时间;解决办法:让线程A阻塞等待条件cond的发生(pthread_cond_wait(cond, mutex)),当线程B实现了cond时,则通知别的正在等待的线程(pthread_cond_signal(cond));
     3、信号量sem
     信号灯可以说是条件变量的升级版。条件变量相当于铃铛,铃铛响后每个挂起的进程还需要自己获得互斥锁并判断所需条件是否满足,信号灯把这两步操作糅合到一起。

五     >>>>>进程之间的通信

     有名管道(pipe)与无名管道(mkfifo)异同点:

     相同:
     1.都是基于文件描述符的的进程间通信方式。2.都可以利用read(),write()函数等文件IO函数进行读写。与普通文件读写区别是管道中数据读完后就没有,数据只能读到一次。3.都不可使用lseek()进行定位操作。4.数据都是先入先出FIFO。5.读写都遵循管道读写规则。
     不同:
     1.无名管道只能用于具有亲缘关系的进程间通信;有名管道可用于并不相关的两个进程之间相互通信。2.无名管道通过pipe函数创建并获得操作的一对文件描述符,具有亲缘关系的进程才能使用;
而有名管道是通过mkfifo函数创建,任何进程都可以根据有名管道文件名及其所在路径利用open()函数打开,close(函数关闭,read()/write()读写。3.无名管道只在内按中有一段锻冲区,只能)疑通功pipe&救剎建并获得读写的文件描述符,而有名管道不光在内核中有一段缓冲区,而且在文件系统中有一个文件名,这个文件名对应了内核中的一段缓冲区.与普通文本文件区别在于有名管道仅仅在文件系统中有一个名字,数据是存放在内存中(内核空间)。

    (摘抄){

     一个房间可以认为是相对封闭不允许外人访问的,但是在某些情况下还是需要相互访问的,比如进程A执行完成后进程B才能执行,那么A需要把它执行完的事情通过某种方式告诉进程B,这就涉及到了进程间的通信,进程间通信的方式有无名管道、有名管道、信号、信号量、共享内存、消息队列、套接字。

     信号是一种比较粗糙的通信方式,只是一个整数,可以有内存产生,也可以有硬件产生

     信号量---semaphore与mutex类似,用于处理同步问题。我们说mutex像是一个只能容纳一个人的洗手间,那么semaphore就像是一个能容纳N个人的洗手间。其实从意义上来说,semaphore就是一个计数锁(我觉得将semaphore翻译成为信号量非常容易让人混淆semaphore与signal),它允许被N个进程获得。当有更多的进程尝试获得semaphore的时候,就必须等待有前面的进程释放锁。当N等于1的时候,semaphore与mutex实现的功能就完全相同。许多编程语言也使用semaphore处理多线程同步的问题。一个semaphore会一直存在在内核中,直到某个进程删除它。

     共享内存与多线程共享global data和heap类似。一个进程可以将自己内存空间中的一部分拿出来,允许其它进程读写。当使用共享内存的时候,我们要注意同步的问题。我们可以使用semaphore同步,也可以在共享内存中建立mutex或其它的线程同步变量来同步。由于共享内存允许多个进程直接对同一个内存区域直接操作,所以它是效率最高的IPC方式。

     消息队列(message queue)与PIPE相类似。它也是建立一个队列,先放入队列的消息被最先取出。不同的是,消息队列允许多个进程放入消息,也允许多个进程取出消息。每个消息可以带有一个整数识别符(message_type)。你可以通过识别符对消息分类 (极端的情况是将每个消息设置一个不同的识别符)。某个进程从队列中取出消息的时候,可以按照先进先出的顺序取出,也可以只取出符合某个识别符的消息(有多个这样的消息时,同样按照先进先出的顺序取出)。消息队列与PIPE的另一个不同在于它并不使用文件API。最后,一个队列不会自动消失,它会一直存在于内核中,直到某个进程删除该队列。}

六     >>>>>upt的服务器与客户端创建。

服务器的创建分为4步:①建立套接字———>②给struct sockaddr_in结构体赋予自身的ip和端口号——>③bind函数绑定——>④recvfrom接收别的客户端发来的信息。

客户端的创建分为3步:①建立套接字———>②给struct sockaddr_in结构体赋予目标的ip和端口号——>③sendto函数发送给目标服务器。

这里我用创建子进程的方法分布将服务端和客户端写进了一个程序里面。

代码参考如下:

 


学习感悟与收获:

        以上就是我对这一周的学习的一个不太全面的总结吧,嵌入式迄今的学习对于我来说还是感受颇深的,一方面是对前面所学知识的感受,感觉学习的东西很多、知识点很杂、有很多细节的地方需要去理解、函数的用法需要理解和记忆,需要在以后的时间里时不时的去回到前面的知识点去重新看,这里的回顾不仅是把遗忘的知识捡起来,而且要在回顾的同时对以前感到困惑的地方有新的理解。另一方面是对现有的知识的应用,学习到这里,无疑是还是难度的,到现在为止对进程之间的通信方式还是存在于认识、并不能很好的去应用,很多时候在使用多时候还需要去翻阅之前的笔记,所以还是需要多去看多去练。另外,我觉的学习嵌入式,自己的编程思维还需磨练,多去做一些练习去开拓自己的思维,学习别人是怎么做的,想一想别人是怎么想到的。让自己在写代码的时候能够更加的严谨。

        至此,希望能在以后的学习之中更进一步,掌握更多的知识。不要停留在幻想,坚持下去才能走得更远。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
sscanf函数是C语言中一个非常常用的函数,它可以将一个字符串按照指定的格式转换成相应的数据类型。在嵌入式开发中,sscanf函数也是非常常见的,因为很多时候需要从串口或者其他外部设备中读取数据,并将其转换成相应的数据类型进行处理。下面是一些sscanf函数的使用技巧: 1. 使用sscanf函数时一定要注意格式字符串的正确性。格式字符串中的占位符必须与待转换的数据类型相对应,否则会发生未知错误。 2. 如果待转换的字符串中包含多个数据,可以使用多个占位符进行转换。例如,如果待转换的字符串为"1,2,3",可以使用" %d,%d,%d"的格式字符串进行转换。 3. 可以使用sscanf函数的返回值来判断转换是否成功。如果返回值等于待转换字符串的长度,则说明转换成功,否则转换失败。 4. 如果待转换的字符串中包含浮点数,可以使用"%f"或者"%lf"的格式字符串进行转换。 5. 如果待转换的字符串中包含十六进制数,可以使用"%x"的格式字符串进行转换。 6. 如果待转换的字符串中包含字符或字符串,可以使用"%c"或者"%s"的格式字符串进行转换。 7. 如果待转换的字符串中包含指针类型的数据,可以使用"%p"的格式字符串进行转换。 总之,在使用sscanf函数时一定要注意格式字符串的正确性,否则很容易出现转换错误的情况。同时,还应该注意sscanf函数返回值的判断,以确保转换的正确性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值