高级io函数与服务器程序规范

来源:互联网 发布:淘宝正的潘多拉 编辑:程序博客网 时间:2024/05/17 23:05

高级io函数

单向管道实现管道pipe(int fd[2]) fd[0]读 fd[1]写

双向管道基本本地的,前三个参数和socket一模一样

 socketpair(int domain,int type, int protocol,int fd[2])

dup函数和dup2函数

dup(fd) 复制一个新的描述符,和原来的一样,总是取得当前系统可用的最小值dup(int fd1,int fd2) 同dup一样,返回一个不小于dup2的整数

代码片段

int connfd = accept( sock, ( struct sockaddr* )&client, &client_addrlength );    if ( connfd < 0 )    {        printf( "errno is: %d\n", errno );    }    else    {        close( STDOUT_FILENO );        dup( connfd );        printf( "abcd\n" );        close( connfd );    }    close( sock );

readv函数和writev函数,readv将数据从文件描述符读到分散的内存块,分散读,readv将分散的内存块写入文件描述符集中写

readv(fd,struct iovec*vector,int count)writev(fd,struct iovec*vector,int count);

两个文件描述符之间直接传输数据 sendfile,为网络上传输文件而设计 零拷贝

sendfile(in_fd,out_fd,off*offset,size_t count);in_fd只能是文件描述符 不能是out_fd只能是socket 不能是文件描述符
if ( connfd < 0 )    {        printf( "errno is: %d\n", errno );    }    else    {        sendfile( connfd, filefd, NULL, stat_buf.st_size );        close( connfd );    }

mmap函数和munmap函数 或者进程间的共享内存,文件映射到内存

mmap(void *start,size_t len,int prot,int fd, int flag)munmap(void *start,size_t len)

splice 两个文件描述符之间移动数据 零拷贝

splice(fd_in,off_in,fd_out,off_out,size_t len,int flag)

tee 两个管道文件描述符之间复制数据 零拷贝,不消耗数据,读后任然可以继续读

tee(fd_in,fd_out,size_t len, int flag) 

fcntl 文件描述符的各种操作

fcntl(fd,int cmd,...)
    int setnoblocking(int fd){        int old_option = fcntl(fd,F_GETFL);        int new_option = old_option | O_NONBLOCK;        fcntl(fd,F_SETTFL,new_option)        return old_option    }

服务器程序规范

系统提供两个日志服务

syslogdrsyslogd更高级的

用户通过syslog()函数和rsyslogd通信

syslog(int priority日志级别,const char* message,...);

改版syslog的默认输出

openlog(char * ident,int logopt,int facility)

设置掩码setlogmask(int)

关闭日志 closelog();

用户信息getuid(),geteuid(),getgid(),getegid(),setuid(uid_t uid) seteuid(uid_t uid) setgid(uid_t uid) setegid(uid_t uid),
uid_t uid = getuid();    uid_t euid = geteuid();    printf( "userid is %d, effective userid is: %d\n", uid, euid );    return 0;

进程间的关系

每个进程属于一个进程组,进程组 getpgid(pid)  setpgetid(pid,pgid)一些关联进程组形成一个回话 getsid(pid) setsid(void) 

系统资源限制

getrlimit(int res,struct rlimit*rlim)   setrlimit(int res,struct rlimit*rlim)RLIMIT_AS  虚拟内存总量RLIMIT_CORE 进程核心转存储文件的大小限制RLIMIT_CPU  cpu时间限制RLIMIT_DATA  进程数据段限制RLIMIT_FSIZE 文件大小限制RLIMIT_NOFILE 文件描述符限制RLIMIT_NPROC 用户创建进程限制RLIMIT_SIGPENDING 挂起的信号量限制RLIMIT_STACK 进程栈内存限制

改变工作目录和当前目录

char* getcwd(char*buf,size_t size)chdir(char *path)chroot(char *path)

linux的函数库设置守护进程

int daemon(int nochdir,int noclose)                工作目录    标准输入输出错误
#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <fcntl.h>bool daemonize();int main(int argc, char const *argv[]){    int i = 1000000;    daemonize();    while(i> 0){        puts("wating ...");        sleep(1);        i--;    }    return 0;}bool daemonize(){    pid_t pid = fork();    if ( pid < 0 )    {        return false;    }    else if ( pid > 0 )    {        exit( 0 );    }    //设置掩码,权限设置    umask( 0 );    // 新建一个回话脱离原来的的会员    pid_t sid = setsid();    if ( sid < 0 )    {        return false;    }    //切换到根目录    if ( ( chdir( "/" ) ) < 0 )    {        /* Log the failure */        return false;    }    close( STDIN_FILENO );//关闭输入    close( STDOUT_FILENO );//关闭输出    close( STDERR_FILENO );//关闭错误    //输入输出到null    open( "/dev/null", O_RDONLY );    open( "/dev/null", O_RDWR );    open( "/dev/null", O_RDWR );    return true;}
0 0