走过路过不要错过
点击蓝字关注我们
本文将为大家介绍鸿蒙轻内核中的进程、线程、内存和网络四大基础功能,包括一些基础概念、实现功能和使用场景等,供想要深入了解鸿蒙操作系统的初学者学习参考。
一、进程
基本概念
从系统的角度看,进程是资源管理单元。进程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它进程运行。
OpenHarmony内核的进程模块可以给用户提供多个进程,实现了进程之间的切换和通信,帮助用户管理业务程序流程。这样用户可以将更多的精力投入到业务功能的实现中。
OpenHarmony内核中的进程采用抢占式调度机制,支持时间片轮转调度方式和FIFO调度机制。
OpenHarmony内核的进程一共有32个优先级(0-31),用户进程可配置的优先级有22个(10-31),最高优先级为10,最低优先级为31。
高优先级的进程可抢占低优先级进程,低优先级进程必须在高优先级进程阻塞或结束后才能得到调度。
每一个用户态进程均拥有自己独立的进程空间,相互之间不可见,实现进程间隔离。
用户态根进程Init由内核态创建,其它用户态进程均由Init进程fork而来。
进程状态说明:
初始化(Init):该进程正在被创建。
就绪(Ready):该进程在就绪列表中,等待CPU调度。
运行(Running):该进程正在运行。
阻塞(Pend):该进程被阻塞挂起。本进程内所有的线程均被阻塞时,进程被阻塞挂起。
僵尸态(Zombies):该进程运行结束,等待父进程回收其控制块资源。
图 1 进程状态迁移示意图
进程状态迁移说明:
Init→Ready:
进程创建或fork时,拿到该进程控制块后进入Init状态,处于进程初始化阶段,当进程初始化完成将进程插入调度队列,此时进程进入就绪状态。
Ready→Running:
进程创建后进入就绪态,发生进程切换时,就绪列表中最高优先级的进程被执行,从而进入运行态。若此时该进程中已无其它线程处于就绪态,则该进程从就绪列表删除,只处于运行态;若此时该进程中还有其它线程处于就绪态,则该进程依旧在就绪队列,此时进程的就绪态和运行态共存。
Running→Pend:
进程内所有的线程均处于阻塞态时,进程在最后一个线程转为阻塞态时,同步进入阻塞态,然后发生进程切换。
Pend→Ready / Pend→Running:
阻塞进程内的任意线程恢复就绪态时,进程被加入到就绪队列,同步转为就绪态,若此时发生进程切换,则进程状态由就绪态转为运行态。
Ready→Pend:
进程内的最后一个就绪态线程处于阻塞态时,进程从就绪列表中删除,进程由就绪态转为阻塞态。
Running→Ready:
进程由运行态转为就绪态的情况有以下两种:
有更高优先级的进程创建或者恢复后,会发生进程调度,此刻就绪列表中最高优先级进程变为运行态,那么原先运行的进程由运行态变为就绪态。
若进程的调度策略为SCHED_RR,且存在同一优先级的另一个进程处于就绪态,则该进程的时间片消耗光之后,该进程由运行态转为就绪态,另一个同优先级的进程由就绪态转为运行态。
Running→Zombies:
当进程的主线程或所有线程运行结束后,进程由运行态转为僵尸态,等待父进程回收资源。
使用场景
进程创建后,用户只能操作自己进程空间的资源,无法操作其它进程的资源(共享资源除外)。用户态允许进程挂起,恢复,延时等操作,同时也可以设置用户态进程调度优先级和调度策略,获取进程调度优先级和调度策略。进程结束的时候,进程会主动释放持有的进程资源,但持有的进程pid资源需要父进程通过wait/waitpid或父进程退出时回收。
功能
OpenHarmony内核系统中的进程管理模块为用户提供下面几种功能:
表 1 进程管理模块功能
功能分类
接口名
描述
备注
进程
fork
创建一个新进程。
-
exit
终止进程。
-
atexit
注册正常进程终止的回调函数。
-
abort
中止进程执行。
-
getpid
获取进程ID。
-
getppid
获取父进程ID。
-
getpgrp
获取调用进程的进程组ID。
-
getpgid
获取进程的进程组ID。
-
setpgrp
设置调用进程的进程组ID。
-
setpgid
设置进程的进程组ID。
-
kill
给进程发送信号。
仅支持1-30号信号的发送。
信号的默认行为不支持STOP及CONTINUE,无COREDUMP功能。
不能屏蔽SIGSTOP、SIGKILL、SIGCONT。
异步信号,发送信号给某进程后,直到该进程被调度后才会执行信号回调(为安全起见,杀死进程的动作是进程自己执行的,内核不能通过信号强制杀死对方)。
进程消亡会发送SIGCHLD给父进程,发送动作无法取消。
无法通过信号唤醒正在睡眠的进程。
wait
等待任意子进程结束并回收子进程资源。
status的值可以由以下宏定义解析:
WIFEXITED(status):如果子进程正常结束,它就返回真;否则返回假。
WEXITSTATUS(status):如果WIFEXITED(status)为真,则可以用该宏取得子进程exit()返回的退出码。
WTERMSIG(status) 仅支持以下情况:子进程触发异常结束后通过WTERMSIG获取的进程退出编号始终为SIGUSR2。
不支持的操作:WIFSTOPPED、WSTOPSIG、WCOREDUMP 、WIFCONTINUED。
waitpid
等待子进程结束并回收子进程资源。
options:不支持WUNTRACED,WCONTINUED;
status的值可以由以下宏定义解析:
WIFEXITED(status):如果子进程正常结束,它就返回真;否则返回假。
WEXITSTATUS(status):如果WIFEXITED(status)为真,则可以用该宏取得子进程exit()返回的退出码。
WTERMSIG(status)仅支持以下情况:子进程触发异常结束后通过WTERMSIG获取的进程退出编号始终为SIGUSR2。
不支持:WIFSTOPPED 、WSTOPSIG、WCOREDUMP 、WIFCONTINUED。
调度
getpriority
获取指定ID的静态优先级。
不支持:PRIO_PGRP、PRIO_USER。
无动态优先级概念,用于设置静态优先级。
setpriority
设置指定ID的静态优先级。
sched_rr_get_interval
获取执行时间限制。
-
sched_yield
系统调用运行进程主动让出执行权。
-
sched_get_priority_max
获取进程静态优先级取值范围的最大值。
调度策略只支持:SCHED_FIFO 、SCHED_RR。
sched_get_priority_min
获取进程静态优先级取值范围的最小值。
sched_getscheduler
获取调度策略。
sched_setscheduler
设置调度策略。
sched_getparam
获取调度参数。
-
sched_setparam
设置调度参数。
-
exec
execl
执行指定的elf格式的用户程序文件。
-
execle
执行指定的elf格式的用户程序文件。
-
execlp
执行指定的elf格式的用户程序文件。
-
execv
执行指定的elf格式的用户程序文件。
-
execve
执行指定的elf格式的用户程序文件。
-
execvp
执行指定的elf格式的用户程序文件。
-
二、线程
基本概念
从系统的角度看,线程是竞争系统资源的最小运行单元。线程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它线程运行。
OpenHarmony内核每个进程内的线程独立运行、独立调度,当前进程内线程的调度不受其它进程内线程的影响。
OpenHarmony内核中的线程采用抢占式调度机制,同时支持时间片轮转调度和FIFO调度方式。
OpenHarmony内核的线程一共有32个优先级(0-31),最高优先级为0,最低优先级为31。
当前进程内高优先级的线程可抢占当前进程内低优先级线程,当前进程内低优先级线程必须在当前进程内高优先级线程阻塞或结束后才能得到调度。
线程状态说明:
初始化(Init):该线程正在被创建。
就绪(Ready):该线程在就绪列表中,等待CPU调度。
运行(Running):该线程正在运行。
阻塞(Blocked):该线程被阻塞挂起。Blocked状态包括:pend(因为锁、事件、信号量等阻塞)、suspend(主动pend)、delay(延时阻塞)、pendtime(因为锁、事件、信号量时间等超时等待)。
退出(Exit):该线程运行结束,等待父线程回收其控制块资源。
图 1 线程状态迁移示意图
线程状态迁移说明:
Init→Ready:
线程创建拿到控制块后为Init状态,处于线程初始化阶段,当线程初始化完成将线程插入调度队列,此时线程进入就绪状态。
Ready→Running:
线程创建后进入就绪态,发生线程切换时,就绪列表中最高优先级的线程被执行,从而进入运行态,但此刻该线程会从就绪列表中删除。
Running→Blocked:
正在运行的线程发生阻塞(挂起、延时、读信号量等)时,该线程会从就绪列表中删除,线程状态由运行态变成阻塞态,然后发生线程切换,运行就绪列表中剩余最高优先级线程。
Blocked→Ready / Blocked→Running:
阻塞的线程被恢复后(线程恢复、延时时间超时、读信号量超时或读到信号量等),此时被恢复的线程会被加入就绪列表,从而由阻塞态变成就绪态;此时如果被恢复线程的优先级高于正在运行线程的优先级,则会发生线程切换,将该线程由就绪态变成运行态。
Ready→Blocked:
线程也有可能在就绪态时被阻塞(挂起),此时线程状态会由就绪态转变为阻塞态,该线程从就绪列表中删除,不会参与线程调度,直到该线程被恢复。
Running→Ready:
有更高优先级线程创建或者恢复后,会发生线程调度,此刻就绪列表中最高优先级线程变为运行态,那么原先运行的线程由运行态变为就绪态,并加入就绪列表中。
Running→Exit:
运行中的线程运行结束,线程状态由运行态变为退出态。若未设置分离属性(PTHREAD_CREATE_DETACHED)的线程,运行结束后对外呈现的是Exit状态,即退出态。
Blocked→Exit:
阻塞的线程调用删除接口,线程状态由阻塞态变为退出态。
使用场景
线程创建后,用户态可以执行线程调度、挂起、恢复、延时等操作,同时也可以设置线程优先级和调度策略,获取线程优先级和调度策略。
功能
OpenHarmony内核系统中的线程管理模块,线程间通信为用户提供下面几种功能:
表 1 线程管理模块功能
头文件
名称
说明
备注
pthread.h
pthread_attr_destroy
销毁线程属性对象。
-
pthread.h
pthread_attr_getinheritsched
获取线程属性对象的调度属性。
-
pthread.h
pthread_attr_getschedparam
获取线程属性对象的调度参数属性。
-
pthread.h
pthread_attr_getschedpolicy
获取线程属性对象的调度策略属性。
OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。
pthread.h
pthread_attr_getstacksize
获取线程属性对象的堆栈大小。
-
pthread.h
pthread_attr_init
初始化线程属性对象。
-
pthread.h
pthread_attr_setdetachstate
设置线程属性对象的分离状态。
-
pthread.h
pthread_attr_setinheritsched
设置线程属性对象的继承调度属性。
-
pthread.h
pthread_attr_setschedparam
设置线程属性对象的调度参数属性。
OpenHarmony:设置线程优先级的参数值越小,线程在系统中的优先级越高;设置参数值越大,优先级越低。
注意:需要将pthread_attr_t线程属性的inheritsched字段设置为PTHREAD_EXPLICIT_SCHED,否则设置的线程调度优先级将不会生效,系统默认设置为PTHREAD_INHERIT_SCHED。
pthread.h
pthread_attr_setschedpolicy
设置线程属性对象的调度策略属性。
OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。
pthread.h
pthread_attr_setstacksize
设置线程属性对象的堆栈大小。
-
pthread.h
pthread_getattr_np
获取已创建线程的属性。
-
pthread.h
pthread_cancel
向线程发送取消请求。
-
pthread.h
pthread_testcancel
请求交付任何未决的取请求。
-
pthread.h
pthread_setcanceltype
设置线程可取消类型。
-
pthread.h
pthread_setcancelstate
设置线程可取消状态。
-
pthread.h
pthread_create
创建一个新的线程。
-
pthread.h
pthread_detach
分离一个线程。
-
pthread.h
pthread_equal
比较两个线程ID是否相等。
-
pthread.h
pthread_exit
终止正在调用的线程。
-
pthread.h
pthread_getschedparam
获取线程的调度策略和参数。
OpenHarmony:支持SCHED_FIFO 、SCHED_RR调度策略。
pthread.h
pthread_join
等待指定的线程结束。
-
pthread.h
pthread_self
获取当前线程的ID。
-
pthread.h
pthread_setschedprio
设置线程的调度静态优先级。
-
pthread.h
pthread_kill
向线程发送信号。
-
pthread.h
pthread_once
使函数调用只能执行一次。
-
pthread.h
pthread_atfork
注册fork的处理程序。
-
pthread.h
pthread_cleanup_pop
删除位于清理处理程序堆栈顶部的例程。
-
pthread.h
pthread_cleanup_push
将例程推送到清理处理程序堆栈的顶部。
-
pthread.h
pthread_barrier_destroy
销毁屏障对象(高级实时线程)
-
pthread.h
pthread_barrier_init
初始化屏障对象(高级实时线程)
-
pthread.h
pthread_barrier_wait
屏障同步(高级实时线程)
-
pthread.h
pthread_barrierattr_destroy
销毁屏障属性对象。
-
pthread.h
pthread_barrierattr_init
初始化屏障属性对象。
-
pthread.h
pthread_mutex_destroy
销毁互斥锁。
-
pthread.h
pthread_mutex_init
初始化互斥锁。
-
pthread.h
pthread_mutex_lock
互斥锁加锁操作。
-
pthread.h
pthread_mutex_trylock
互斥锁尝试加锁操作。
-
pthread.h
pthread_mutex_unlock
互斥锁解锁操作。
-
pthread.h
pthread_mutexattr_destroy
销毁互斥锁属性对象。
-
pthread.h
pthread_mutexattr_gettype
获取互斥锁类型属性。
-
pthread.h
pthread_mutexattr_init
初始化互斥锁属性对象。
-
pthread.h
pthread_mutexattr_settype
设置互斥锁类型属性。
-
pthread.h
pthread_mutex_timedlock
使用超时锁定互斥锁。
-
pthread.h
pthread_rwlock_destroy
销毁读写锁。
-
pthread.h
pthread_rwlock_init
初始化读写锁。
-
pthread.h
pthread_rwlock_rdlock
获取读写锁读锁操作。
-
pthread.h
pthread_rwlock_timedrdlock
使用超时锁定读写锁读锁。
-
pthread.h
pthread_rwlock_timedwrlock
使用超时锁定读写锁写锁。
-
pthread.h
pthread_rwlock_tryrdlock
尝试获取读写锁读锁操作。
-
pthread.h
pthread_rwlock_trywrlock
尝试获取读写锁写锁操作。
-
pthread.h
pthread_rwlock_unlock
读写锁解锁操作。
-
pthread.h
pthread_rwlock_wrlock
获取读写锁写锁操作。
-
pthread.h
pthread_rwlockattr_destroy
销毁读写锁属性对象。
-
pthread.h
pthread_rwlockattr_init
初始化读写锁属性对象。
-
pthread.h
pthread_cond_broadcast
解除若干已被等待条件阻塞的线程。
-
pthread.h
pthread_cond_destroy
销毁条件变量。
-
pthread.h
pthread_cond_init
初始化条件变量。
-
pthread.h
pthread_cond_signal
解除被阻塞的线程。
-
pthread.h
pthread_cond_timedwait
定时等待条件。
-
pthread.h
pthread_cond_wait
等待条件。
-
semaphore.h
sem_destroy
销毁指定的无名信号量。
-
semaphore.h
sem_getvalue
获得指定信号量计数值。
-
semaphore.h
sem_init
创建并初始化一个无名信号量。
-
semaphore.h
sem_post
增加信号量计数。
-
semaphore.h
sem_timedwait
获取信号量,且有超时返回功能。
-
semaphore.h
sem_trywait
尝试获取信号量。
-
semaphore.h
sem_wait
获取信号量。
-
三、内存
基本概念
内存管理是开发过程中必须要关注的重要过程,它包括内存的分配、使用和回收。
良好的内存管理对于提高软件性能和可靠性有着十分重要的意义。
使用场景
针对用户态开发,OpenHarmony内存提供了一套内存系统调用接口,支持内存的申请释放、重映射、内存属性的设置等,还有C库的标准内存操作函数。
功能
表 1 标准C库相关接口
头文件
接口
功能
strings.h
int bcmp(const void *s1, const void *s2, size_t n)
比较字节序列。
strings.h
void bcopy(const void *src, void *dest, size_t n)
拷贝字节序列。
strings.h
void bzero(void *s, size_t n)
写入零值字节。
string.h
void *memccpy(void *dest, const void *src, int c, size_t n)
拷贝src 所指的内存内容前n 个字节到dest 所指的地址上。复制时检查参数c 是否出现,若是则返回dest 中值为c 的下一个字节地址。
string.h
void *memchr(const void *s, int c, size_t n)
在s所指内存的前n个字节中查找c。
string.h
int memcmp(const void *s1, const void *s2, size_t n)
内存比较。
string.h
void *memcpy(void *dest, const void *src, size_t n)
内存拷贝。
string.h
void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen)
找到一个子串。
string.h
void *memmove(void *dest, const void *src, size_t n)
内存移动。
string.h
void *mempcpy(void *dest, const void *src, size_t n)
拷贝内存区域。
string.h
void *memset(void *s, int c, size_t n)
内存初始化。
stdlib.h
void *malloc(size_t size)
申请内存。
stdlib.h
void *calloc(size_t nmemb, size_t size)
申请内存并清零。
stdlib.h
void *realloc(void *ptr, size_t size)
重分配内存。
stdlib.h/malloc.
void *valloc(size_t size)
分配以页对齐的内存。
stdlib.h
void free(void *ptr)
释放内存。
malloc.h
size_t malloc_usable_size(void *ptr)
获取从堆分配的内存块的大小。
unistd.h
int getpagesize(void)
获取页面大小。
unistd.h
void *sbrk(intptr_t increment)
更改数据段大小。
差异接口详细说明:
mmap
函数原型:
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
**函数功能:**申请虚拟内存。
参数说明:
参数
描述
addr
用来请求使用某个特定的虚拟内存地址。如果取NULL,结果地址就将自动分配(这是推荐的做法),否则会降低程序的可移植性,因为不同系统的可用地址范围不一样。
length
内存段的大小。
prot
用于设置内存段的访问权限,有如下权限:
flags
控制程序对内存段的改变所造成的影响,有如下属性:
fd
打开的文件描述符。
offset
用以改变经共享内存段访问的文件中数据的起始偏移值。
说明: mmap与Linux实现差异详见与Linux标准库的差异章节。
返回值:
-
成功返回:虚拟内存地址,这地址是页对齐。
失败返回:(void *)-1。
MAP_PRIVATE:内存段私有,对它的修改值仅对本进程有效。
MAP_SHARED:把对该内存段的修改保存到磁盘文件中。
PROT_READ:允许读该内存段。
PROT_WRITE:允许写该内存段。
PROT_EXEC:允许执行该内存段。
PROT_NONE:不能访问。
munmap接口
函数原型:
int munmap(void *addr, size_t length);
**函数功能:**释放虚拟内存。
参数说明:
参数
描述
addr
虚拟内存起始位置。
length
内存段的大小。
返回值:
-
成功返回0。
失败返回-1。
mprotect接口
函数原型:
int mprotect(void *addr, size_t length, int prot);
**函数功能:**修改内存段的访问权限。
参数说明:
参数
描述
addr
内存段起始地址,必须页对齐;访问权限异常,内核将直接抛异常,kill该进程,而不会产生SIGSEGV信号给当前进程。
length
内存段的大小。
prot
内存段的访问权限,有如下定义:
返回值:
-
成功返回0。
失败返回-1。
PROT_READ:允许读该内存段。
PROT_WRITE:允许写该内存段。
PROT_EXEC:允许执行该内存段。
PROT_NONE:不能访问。
mremap接口
函数原型:
void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, void new_address);
**函数功能:**重新映射虚拟内存地址。
参数说明:
参数
描述
old_address
需要扩大(或缩小)的内存段的原始地址。注意old_address必须是页对齐。
old_size
内存段的原始大小。
new_size
新内存段的大小。
flags
如果没有足够的空间在当前位置展开映射,则返回失败
返回值:
-
成功返回:重新映射后的虚拟内存地址。
失败返回:((void *)-1)。
MREMAP_MAYMOVE:允许内核将映射重定位到新的虚拟地址。
MREMAP_FIXED:mremap()接受第五个参数,void *new_address,该参数指定映射地址必须页对齐;在new_address和new_size指定的地址范围内的所有先前映射都被解除映射。如果指定了MREMAP_FIXED,还必须指定MREMAP_MAYMOVE。
四、网络
基本概念
网络模块实现了TCP/IP协议栈基本功能,提供标准的POSIX socket接口。
说明: 当前系统使用lwIP提供网络能力。
使用场景
针对用户态开发,OpenHarmony内核提供了一套网络功能系统调用接口,支持socket的创建关闭、数据收发、网络属性的设置等,通过C库提供标准的POSIX socket函数供开发者使用。
功能
表 1 标准C库相关接口
头文件
接口
功能
sys/socket.h
int accept(int socket, struct sockaddr *address, socklen_t *address_len)
接受连接。
sys/socket.h
int bind(int s, const struct sockaddr *name, socklen_t namelen)
socket与IP地址绑定。
sys/socket.h
int shutdown(int socket, int how)
关闭连接。
sys/socket.h
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
获取对端地址。
sys/socket.h
int getsockname(int s, struct sockaddr *name, socklen_t *namelen)
获取本地地址。
sys/socket.h
int getsockopt(int s, struct sockaddr *name, socklen_t *namelen)
获取socket属性信息。
sys/socket.h
int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
配置socket属性。
unistd.h
int close(int s)
关闭socket。
sys/socket.h
int connect(int s, const struct sockaddr *name, socklen_t namelen)
连接到指定的目的IP。
sys/socket.h
int listen(int sockfd, int backlog)
listen连接本socket的请求。
sys/socket.h
ssize_t recv(int socket, void *buffer, size_t length, int flags)
接收socket上收到的数据。
sys/socket.h
ssize_t recvmsg(int s, struct msghdr *message, int flags)
接收socket上收到的数据,可使用更丰富的参数。
sys/socket.h
ssize_t recvfrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len)
接收socket上收到的数据,可同时获得数据来源IP地址。
sys/socket.h
ssize_t send(int s, const void *dataptr, size_t size, int flags)
通过socket发送数据。
sys/socket.h
ssize_t sendmsg(int s, const struct msghdr *message, int flags)
通过socket发送数据,可使用更丰富的参数。
sys/socket.h
ssize_t sendto(int s, const void *dataptr, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
通过socket发送数据,可指定发送的目的IP地址。
sys/socket.h
int socket(int domain, int type, int protocol)
创建socket。
sys/select.h
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
多路复用。
sys/ioctl.h
int ioctl(int s, int request, ...)
socket属性获取、设置。
arpa/inet.h
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
网络地址格式转换:将二进制格式IP地址转换为字符串格式。
arpa/inet.h
int inet_pton(int af, const char *src, void *dst)
网络地址格式转换:将字符串格式IP地址转换为二进制格式。
与标准接口差异详细说明:
sendmsg
函数原型:
ssize_t sendmsg(int s, const struct msghdr *message, int flags)
**函数功能:**发送消息。
参数说明:
参数
描述
s
套接字。
message
待发送的消息,不支持发送ancillary消息。
flags
用于指定发送消息时行为特性,有如下行为特性:
返回值:
-
成功返回:已发送的消息长度(字节数)。
失败返回:-1,并设置errno。
MSG_MORE:允许将多次发送的消息进行拼包发送。
MSG_DONTWAIT:非阻塞操作。
recvmsg
函数原型:
ssize_t recvmsg(int s, struct msghdr *message, int flags)
**函数功能:**接收消息。
参数说明:
参数
描述
s
套接字。
message
存放接收的消息,不支持接收ancillary消息。
flags
用于指定接收消息时行为特性,有如下行为特性:
返回值:
-
成功返回:已接收的消息长度(字节数)。
失败返回:-1,并设置errno。
MSG_PEEK:允许预读消息而不取走。
MSG_DONTWAIT:非阻塞操作。
ioctl
函数原型:
int ioctl(int s, int request, ...)
**函数功能:**获取或设置socket属性。
参数说明:
参数
描述
s
套接字
request
对socket属性要进行的操作,当前支持如下操作:
返回值:
-
成功返回:0。
失败返回:-1,并设置errno。
FIONREAD:获取socket当前可读取的数据大小(字节数)。
FIONBIO:设置socket是否非阻塞。
往期精彩推荐
腾讯、阿里、滴滴后台面试题汇总总结 — (含答案)
面试:史上最全多线程面试题 !
最新阿里内推Java后端面试题
JVM难学?那是因为你没认真看完这篇文章
—END—
关注作者微信公众号 —《JAVA烂猪皮》
了解更多java后端架构知识以及最新面试宝典
你点的每个好看,我都认真当成了
作者:恰饭君
出处:https://my.oschina.net/u/4518252/blog/4557433