以前看的书,记录在本子上。现在记录到博客中同时也在复习一遍。
Linux平台编程环境:
使用的工具有:vim,gcc,make和gdb。不过我现在使用的是eclipse定制版。
文件系统:
"UNIX下一切皆是文件"。文件分为:普通文件(二进制文件)、字符设备文件(控制台、串口等)、块设备文件(磁盘等)和SOCKET文件。
相关常用命令:ls,df,mount,mkfs,fdisk等。
虚拟文件系统—VFS:
是Linux内核实现的一种架构,为用户空间提供统一的文件操作接口。
--文件描述符:
文件描述符表示普通文件和设备文件,是一个整形的数据,所有对文件的操作都是通过它实现--需要文件描述符做参数。文件描述符是文件系统中连接用户空间和内核空间的枢纽。
系统中有3个已分配的文件描述符:
标准输入(0)、标准输出(1)、标准错误(2)。
--打开文件:
头文件:<sys/types.h>,<sys/stat.h>,<fcntl.h>
原型:int open(const char* pathname,int flags);
int open(const char* pathname,int flags,mode_t mode);
返回值:返回文件描述符,在出错时返回-1。
参数:pathname为路径文件名,flags指定打开标志(O_RDONLY,
O_WRONLY,O_RDWR,O_APPEND,O_CREAT,O_EXCL,O_TRUNC),
而mode则需要配合O_CREAT使用,表示打开文件权限。
--创建文件:
头文件:<sys/types.h>,<sys/stat.h>,<fcntl.h>
原型:int create(const char* pathname,mode_t mode);
等价于:open(pathname,O_WRONLY|O_CREAT|O_TRUNC,mode);
--关闭文件:
头文件:<unistd.h>
原型:int close(int fd);
返回值:成功时返回0,否则返回-1。
--读文件:
头文件:<unistd.h>
原型:ssize_t read(int fd,void* buf,size_t count);
返回值:成功时返回实际读取的数据大小,否则返回-1。
参数:fd是文件描述符,buf是读取的数据存放的位置,count是希望读取数据
的大小--一般是buf的大小。
--写文件:
头文件:<unistd.h>
原型:ssize_t write(int fd,const void* buf,size_t count);
返回值:出错时返回-1,否则返回写入的数据大小。
PS:write()通常把数据写入系统缓存中,而由系统决定什么时候写入设备。
--文件偏移:
头文件:<sys/types.h>,<unistd.h>
原型:off_t lseek(int fd,off_t offset,int whence);
返回值:成功时返回偏移量—即offset,否则返回-1。
参数:fd表示文件描述符,offset是偏移量,whence表示偏移的参照(
SEEK_SET(开头),SEEK_CUR(当前),SEEK_END(结尾))。
--文件状态查询:
头文件:<sys/types.h>,<sys/stat.h>,<unistd.h>
原型:int stat(const char* path,struct stat* buf);
int fstat(int fd,struct stat* buf);
int lstat(const char* path,struct stat* buf);
返回值:成功时返回0,否则返回-1。
参数:第一个参数指定查询对象,第二个参数则是查询状态结果。
--文件属性(获取和改变已打开文件的性质):
头文件:<unistd.h>,<fcntl.h>
原型:int fcntl(int fd,int cmd);
int fcntl(int fd,int cmd,long arg);
int fcntl(int fd,int cmd,struct flock* lock);
返回值:出错返回-1。
用法:复制得到新文件描述符(cmd=F_DUPFD),获得/设置文件描述符
(F_GETFD,F_SETFD),获得/设置文件状态值(F_GETFL,F_SETFL),
获得/设置信号发送对象(F_GETOWN,FSETOWN,FGETSIG,
F_SETSIG),获得/设置记录锁(F_GETLK,F_SETLK,F_SETLKW),
获得/设置文件租约(F_GETLEASE,F_SETLEASE)。
文件状态标志:O_RDONLY,O_WRONLY,O_RDWR,O_APPEND,
O_NONBLOCK(非阻塞),O_SYNC(写等待),O_ASYNC(同步)
--文件I/O控制:
头文件:<sys/ioctl.h>
原型:int ioctl(int fd,int request,…);
--文件空间映射mmap()函数:
将文件或设备空间映射到内存中,可以通过对映射后的内存空间存取来获得与存取文件一致的控制方式,不必再使用read(),write()函数。
进程、线程和同步:
--进程数据结构:
系统中定义的进程号类型为pid_t(实际为unsigned int类型)。
--获取进程号:
头文件:<sys/types.h>,<unistd.h>
原型:pid_t getpid(void); --获取当前进程号
pid_t getppid(void); --获取父进程号
--进程创建之进程复制:
头文件:<sys/types.h>,<unistd.h>
原型:pid_t fork(void);
返回值:出错返回-1。
使用:在父进程中的返回复制的子进程的ID,而在子进程中返回0。可以根据
返回值的不同判断是父进程还是子进程。
--进程创建之system()方法:
头文件:<stdlib.h>
原型:int system(const char* cmd);
返回值:失败时返回-1,成功返回进程状态值。
功能:调用shell中的命令(参数cmd)在另一个进程中执行,调用system()的
进程阻塞等待cmd执行完成。
--进程创建之exec()系列函数:
与system()方法不同的是会用新进程替换原进程—即PID不变。
多线程:
--数据结构:
线程ID类型为pthread_t(实际为unsigned long int类型)。
--相关函数:
头文件:<pthread.h>,PS:一般还需要连接动态库(-lpthread)。
相关函数:pthread_craete(),pthread_exit()和pthread_join();
--线程属性:
相关数据结构:pthread_attr_t
相关函数:pthread_attr_init();
--同步之互斥量:
相关数据结构:pthread_mutex_t
相关函数:pthread_mutex_init(),pthread_mutex_destroy(),
pthread_mutex_lock(),pthread_mutex_trylock(),
pthread_mutex_unlock();
--同步之信号量:
线程的信号量与进程的信号量类似。
进程间通信(IPC)和同步:
--管道:
管道是把两个进程间的标准输入和标准输出连接起来的机制。
在shell中用"|"表示。
头文件:<unistd.h>
原型:int pipe(int filedes[2]);
返回值:成功时返回0,否则返回-1。
参数说明:filedes[0]是读操作,filedes[1]是写操作。
PS:
相关还有命名管道和消息队列(内核地址空间中的内部链表)。
相关函数有:
mkfifo(),ftok(),msgget(),msgsend(),msgrcv(),msgctl().
--信号量:
信号量是一种计数器,用来控制对多个进程共享的资源所进行的访问。
信号量通常被用作一个锁机制。
相关函数:ftok(),semget(),semop(),semctl()。
--共享内存:
共享内存是IPC最快捷的方式。
相关函数:ftok(),shmget(),shmat(),shmdt(),shmctl()。
--信号(通信机制):
用于在一个或多个进程之间传递异步信号。
可以用"kill –l"查看系统定义的信号。
进程可以屏蔽大多数的信号,除了SIGSTOP(暂停)和SIGKILL(退出)。
--信号截取函数:
头文件:<signal.h>
原型:typedef void (*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);
参数:signum指定要截取的信号,sighandler_t是用户指定的信号处理方式。
--向进程发送信号:
相关函数:kill()是向其他进程,raise()向本进程。
网络编程:
--基础:
不同的协议族有不同的地址结构,以sockaddr_开头。
其中以太网为sockaddr_in.
通用套接字数据结构为:struct sockaddr;(16字节)
--基础函数:
头文件:<sys/types.h>,<sys/socket.h>
原型:
int socket(int domain,int type,int protocol);
int shutdown(int s,int how);
int connect(int sockfd,struct sockaddr* addr,int addrlen);
int bind(int sockfd,const struct sockaddr* my_addr,
socklen_t addrlen);
int listen(int sockfd,int backlog);
int accept(int sockfd,struct sockaddr* addr,socklen_t*addrlen);
--I/O函数之文件读写:
可以使用文件的read()和write()函数。
--I/O函数之二:
头文件:<sys/types.h>,<sys/socket.h>
原型:ssize_t recv(int sockfd,void* buf,size_t len,int flags);
ssize_t send(int sockfd,const void* buf,size_t len,int flags);
--I/O函数之三:
头文件:<sys/uio/h>
原型:ssize_t readv(int fd,struct iovec* vector,int count);
ssize_t writev(int fd,const struct iovec* vector,int count);
--I/O函数之四:
头文件:<sys/types.h>,<sys/socket.h>,<sys/uio.h>
原型:ssize_t recvmsg(int fd,struct msghdr* msg,int flags);
ssize_t sendmsg(int fd,const struct msghdr* msg,int flags);
--select模式:
头文件:<sys/select.h>,<sys/time.h>,<sys/types.h>,<unistd.h>
原型:int select(int fd,fd_set* readfds,fd_set* writefds,
fd_set* exceptfds,struct timeval* timeout);
--poll模式:
头文件:<poll.h>
原型:int poll(struct pollfd* fds,nfds_t nfds,int timeout);
因为书已经还回去了,所以就是copy的笔记本而不能做深拷贝了。
还是需要多编码了。。。