用户编程笔记

一:Process(进程)
是程序执行的过程,包括执行,等待,就绪.process并行运行在虚拟空间,包括code,data,stack部分,
     分为user mode和kernel mode.
 启动:前台启动,后台启动,调度启动.
 调度命令:ps -ef; Nice; kill; crontab(至后台).

创建进程:  
 pid_t fork(void)       sys/type.h,unistd.h
  result=0:  child process
   1:  error
   Oth:father process
 pid_t vfork(void) 
     copy-on-write
执行进程: 
 int execl(const char *path, const char *arg, ...) list unistd.h
 int execv(const char *path, char *const argv[]) vertor
 int execle(const char *path, const char *arg, ..., char *const envp[])
 int execve(const char *path, char *const argv[], char *const envp[])
 int execlp(const char *file, const char *arg, ...)
 int execle(const char *file, const char *arg, ..., char *const envp[])
  char *arg[] = {"env", "NULL"};
  char *envp[] = {"PATH=/tmp", "USER=sunq", NULL};
  if(execve("/bin/env", arg, ,envp) < 0)
  { perror("execve error:"); }
退出进程: 
 void exit(int status)  exit(0);退出并保存buffer stdlib.h
 void _exit(int status) 直接退出   unistd.h

父进程阻塞并等待:直到子进程结束或接到signal
 pid_t wait(int *status)     sys/type.h,sys/wait.h
  *status =NULL:不管状态
   !=NULL:指定status结束的子进程
  pid_t:结束的子进程的进程号.
 pid_t waitpid(pid_t pid, int *status, int options)
  pid=0,<-1:同组的.
      -1:任何的子进程.
      >0:指定的.
  option=WNOHANG: 父进程不阻塞,直接返回.
   WUNTRACED: 阻塞到指定status出现
   0:  阻塞
守护进程:
 五步: fork()
  openlog("this process name", LOG_PID, LOG_DAEMON) 创建一个连接到系统日志,/var/log/messages
  setsid()<0       创建新的会话组,并任组长.
  syslog(LOG_ERR, "%s/n", "setsid err")   写入信息, syslog.h
  chdir("/") 工作目录改为根目录
  unmask(0) 文件权限为0
  for(i=0;i<MAXFILE;i++)
  close(i); 关闭控制终端文件.
  
二:threads(线程)
多线程共用一个进程的文件描述,信号处理和用户地址空间。却创建了多个线程控制表和堆栈寄存器。
分用户级线程(一个阻塞会引起多个阻塞)和核心级线程(可以调度)。1对1,1对多(多处理器).
2.6.13使用NPTL(Native POSIX Thread Library),仍是1:1模型.

创建线程:
 int pthread_create(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)  pthread.h
 通过设置属性CLONE_VM,CLONE_FS,CLONE_FILES(共享文件描述符表)CLONE_SIGHAND(共享信号句柄表)和CLONE_PID(共享进程ID)来调用__clone(),
 __clone设置栈并调用do_fork()这个系统调用.

exit线程:
 void pthread_exit(void *retval)

父线程同步等待退出:
 int pthread_join(pthread_t th, void **thread_return)

abort线程:
 int pthread_cancel(pthread_t thread)  
  相当于abort向目标线程发Cancel信号,而pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、   sem_wait()、sigwait()以及read()、write()等会引起阻塞的系统调用都是Cancelation-point.
 int pthread_setcancelstate(int state, int *oldstate) 收到cancel信号后设为CANCLED状态或忽略cancel信号继续运行
 int pthread_setcanceltype(int type, int *oldtype)  立即cancel或延迟到Cancelation-point
 int pthread_testcancel(void)     检查是否处于Canceld状态,是则进行取消动作,否则直接返回

线程属性:
 int pthread_attr_init(pthread_attr_t *attr)
 int pthread_attr_setscope(pthread_attr_t *attr, int scope) 绑定时间片,和内核线程一起调度
 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)脱离和主线程同步,当退出时立即释放资源
 int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param)优先级设定
        schedpolicy 调度策略,SCHED_OTHER(默认值), SCHED_RR,SCHED_FIFO
        inheritsched  使用新的还是继承调度策略

用来处理exit,cancel退出的cleanup:(atexit)
 void pthread_cleanup_push(void(*routine), (viod*), void *arg)
 void pthread_cleanup_pop(int execute)    非0:弹出程序并执行,0:不执行
  成队出现,设定非正常exit,cencel时释放资源的函数,在pop时执行。
   pthread_cleanup_push(pthread_mutex_unlock, (void*)&mut);
   pthread_mutex_lock(&mut);
   .../* do some work */
   pthread_mutex_unlock(&mut);
   pthread_cleanup_pop(0)
互斥mutex:
 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr)
  mutexattr :PTHREAD_MUTEX_INITIALIZER   加锁后阻塞另一个要加锁的线程.
    :PTHREAD_RECURSIVE_MUTEX_INITIALIZER 加锁后阻塞另一个要加锁的线程,并计数.
    :PTHREAD_ERRORCHECK_MUTEX_INITIALIZER 加锁后不阻塞另一个要加锁的线程而返回EDEADLK错误代码.
 int pthread_mutex_lock(pthread_mutex_t *mutex)
 int pthread_mutex_trylock(pthread_mutex_t *mutex)
 int pthread_mutex_unlock(pthread_mutex_t *mutex)
 int pthread_mutex_destroy(pthread_mutex_t *mutex)

条件变量:
 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
  线程在锁定了一个互斥后,经常需要某个条件到来,则用pthread_cond_wait阻塞并检查指定的条件,没有满足就解锁指定的互斥,进入睡眠,直到条件满  足后重新锁定该互斥,并唤醒被挂起的线程。
 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
 int pthread_cond_destroy(pthread_cond_t *cond)
 int pthread_cond_signal(pthread_cond_t *cond)
 int pthread_cond_broadcast(pthread_cond_t *cond)

三,IPC:(同步异步,通讯)
unix pipe:在进程间以半双工方式通信,存在于内存.
 unistd.h
 int pipe(int fd[2])      
  创建无名管道,在进程组里通信,使用2个文件描述符,一个读fd[0],一个写fd[1],一般通过fork来继承创建的管道,close(pipe_fd[0])等可以关闭
  一个方向的通道.read(fd[0],buf,100),write(fd[1],buf,5)进行读写.
 FILE *popen(const char *command, const char *type) 
  创建标准流管道, fd=popen("ps -ef","r/w"),文件指针连接到comamnd的输入/输出.相当于创建管道->fork->在父子进程关闭不需要的文件描述符->  exec->执行命令这个过程
 int pclose(FILE *stream) 关闭标准流管道
 int mkfifo(const char *fielname, mode_t mode)  
  有名管道,在2个进程间通信,建立后可以象文件一样操作. if( mkfifo("/tmp/myfifo", O_CREAT|O_EXEC|)<0 )

unix signal:异步通讯,可以在用户和内核中进行,是对中断机制的一种模拟.
 signal.h,sys/types.h
 int kill(pid_t pid, int sig)     发送signal到指定的用户组的所有进程.
 int raise(int sig)       发送一个signal给自己.
 unsignted int alarm(unsigned int second)    定时发送一个signal给自己.
 int pause(void)       pause自己直到捕捉到signal
 void (*signal(int signum, void(*handler)(int)))(int)  用指定函数替代原signal本进程指定的操作
  整体是一个带int的函数指针,带2个参数,signum和*handle函数指针
 int sigempty(sigset_t *set)
 int sigfillset(sigset_t *set)
 int sigaddset(sigset_t *set,int signum)
 int sigdelset(sigset_t *set,int signum)
 int sigismember(sigset_t *set,int signum)   初始化一个信号集
 int sigprocmask(int how,const sigset_t *set,sigset_t *oset) 改变当前进程的信号集
    how=SIG_BLOCK,SIG_UNBLOCK,SIG_SETMASK;   sigprocmask(SIG_BLOCK,&set,NULL)
 int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact) 设定新的sigaction
    struct sigaction{
     void (*sa_handler)(int signo); 信号关联函数,SIG_DFL;SIG_IGN..
     sigset_t ds_mask;   信号集 
     int sa_flags;    SA_NODEFER|SA_NOCLDSTOP|SA_RESTART|SA_ONESHOT
     void (*sa_restore)(void);  
    }
 int sigpending(sigset_t *set)     当允许运行时,用sigpending判断是否有阻塞了的signal.
  Example: sigset_t set;
  sigemptyset(&set); sigaddset(&set,SIGQUIT); sigprocmask(SIG_BLOCK,&set,NULL); sigemptyset(&action1.sa_mask);
  action1.sa_handler=myfunc; sigaction(SIGINT,&action1,NULL)
posix shm
 #ifdef _POSIX_MAPPED_FILES
 void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
  prot:访问权限,PROT_READ,PROT_WRITE,PROT_EXEC,PROT_NONE(不可访问)
  flags:MAP_SHARED,MAP_PRIVATE,MAP_FIXED
  fd:映射的文件符
 int munmap(void *start, size_t length)

posix sem
 semaphore.h
 int seminit(sem_t *sem, int pshared, uint value)   pshared=0
 int sem_wait(sem_t *sem)       P操作,信号量的值减1,小于0时将阻塞.
 int sem_trywait(sem_t *sem)
 int sem_post(sem_t *sem)       V操作
 int sem_getvalue(sem_t *sem)
 itn destory(sem_t *sem)
 
systemV shm:从内核的预留内存空间,映射一部分到进程的私有地址空间.实现多个进程间数据共享,当然要考虑同步机制.
 sys/type.h,sys/ipc.h/,sys/shm.h
 int shmget(key_t key, int size, int shmflg)    申请内存.IPC_PRIVATE,shmflg:权限值   
 int *shmat(int shmid,const void *shmaddr,int shmflg)   映射内核内存和用户空间
 int shmdt(const void *shmaddr)      撤消映射

systemV sem:信号量,根据PV原理实现大型数据的同步.
 sys/type.h,sys/ipc.h,sys/sem.h
     struct sembuf{ushort sem_num; 要操作的信号在信号集里的编号
     short sem_op;  信号的值+sem_op, 可以用来做PV操作,为正,占用资源.为负,阻塞并释放资源.0,阻塞到信号量为0
       short sem_flg; IPC_NOWAIT(并返回出错),IPC_UNDO(退出进程时恢复信号量的值)
       }
 int semget(key_t key, int sems, int semflg)    申请和获得semid,包含sems个信号集
 int semop(int semid, struct sembuf *sops, unsigned nsops)  操作信号量
      nsops:信号集中信号的数量.
   调用成功都返回0。失败返回-1,errno被设为以下的某个值:
   E2BIG:一次对信号的操作数超出系统的限制
   EACCES:调用进程没有权能执行请求的操作,并且不具有CAP_IPC_OWNER权能
   EAGAIN:信号操作暂时不能满足,需要重试
   EFAULT:sops或timeout指针指向的空间不可访问
   EFBIG:sem_num指定的值无效
   EIDRM:信号集已被移除
   EINTR:系统调用阻塞时,被信号中断
   EINVAL:参数无效
   ENOMEM:内存不足
   ERANGE:信号所允许的值越界
 int semctl(int semid, int semnum, int cmd, union semun arg)  控制信号量的设定
  cmd: IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。
         IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。
         IPC_RMID将信号量集从内存中删除。
         GETALL用于读取信号量集中的所有信号量的值。
         GETNCNT返回正在等待资源的进程数目。
         GETPID返回最后一个执行semop操作的进程的PID。
         GETVAL返回信号量集中的一个单个的信号量的值。
         GETZCNT返回这在等待完全空闲的资源的进程数目。
         SETALL设置信号量集中的所有的信号量的值。
         SETVAL设置信号量集中的一个单独的信号量的值。  
  
systemV mq:消息队列存在于内核空间,由内核维护.
 sys/type.h,sys/ipc.h,sys/shm.h
 struct msqid_ds{ struct ipc_perm *msg_prem;
      struct msg *msg_first;
      struct msg *msg_last;
      ...};
 int msgget(key_t key, int flag)      申请和获得msgid,flag:IPC_CREAT|0666
 int msgsnd(int msqid, const void *msgbuf, size_t size, int flag) 发message到mq.
           struct msgbuf{long mtype;char mtex[1]};
           flag:IPC_NOWAIT,0:阻塞至发送.
 int msgrcv(int msqid, struct msgbuf *msgbuf, int size, long msgtype, int flag)
           msgtype:0  接收第一个msg
             >0 接收第一个类型为msgtype的消息
             <0  接收第一个最小且小于此绝对值的类型
           flag: MSG_NOERROR,IPC_NOWAIT,0
 int msgctl(int msgid, int cmd, sturct msqid_ds *buf)   控制消息队列
           cmd:IPC_STAT 读取msqid_ds的内容,放入buf
               IPC_SET 写入msqid_ds的ipc_perm
               IPC_RMID 移走消息队列

四,网络编程:
 应用层协议Application:HTTP,FTP,TELNET
 传输层协议Transport:TCP(为应用程序提供可靠的通讯连接,大量数据传输),UDP(无通讯连接,少量数据或安全性低的(video)传输)
 网络层协议Internet:ICMP(发送有关数据包的传送错误的协议),IGMP(向多路广播路由器报告主机组成员的协议),IPv4,IPv6
 网络接口层协议link:ARP,RARP(获得同一网络层中的硬件地址),MPLS(多协议标签协议)
    TCP协议里的三次握手:client->  syn J   ->server
     client<-   syn k,ack J+1  <-server
     client->     ack k+1       ->server
    同时TCP实体采用的基本协议还是个滑动窗口协议.

 

图片1

   
    TCP数据报头: 
  ACK:带不带确认号,PSH:接收到直接送app,RST:复位,SYN:连接时用,FIN:断开连接

 

 

图片2


    UDP数据报头: 
1,数据结构
 netinet/in.h
 struct sockaddr{
  ushort sa_family;  AF_IENT(ipv4),AF_INET6(ipv6),AF_LOCAL(UNIX域协议),AF_LINK(链路地址协议),AF_KEY(密钥socket)
  char sa_date[14];  14字节的协议地址,包括该socket的IP地址和端口号
 }
 struct sockaddr_in{
  short int sa_family;  地址族
  unsigned short int sin_port;端口号
  struct in_addr sin_addr; IP地址
  unsigned char sin_zero[8]; 填0以保持和sockaddr一样大小
 }
2,大小端模式下,CPU和Internet间的数据转化:
 uint16_t htons(unit16_t host16bit)
 uint16_t ntohs(unit16_t net16ibt)
 uint32_t htonl(unit32_t host32bit)
 unit32_t ntohl(unit32_t net32bit)
3,地址格式的转化:192.168.0.189 <-> socket中的二进制
 arpa/inet.h
 int inet_pton(int family, const char *strptr, void *addptr)
 int inet_ntop(int family, void *addptr, const char *strptr)
4,主机名和IP地址间的转化:
 struct hostent{
  char *h_name;   主机名
  char **h_alisees;  别名
  int h_addrtype;  地址类型
  int h_length;   地址长度
  char **h_addr_list;  指向地址指针数组的指针
  }
 struct addinfo{
  int ai_flags;   AI_PASSIVE,AI_CANONNAME
  int ai_family;  地址族
  int ai_socktype;  socket类型
  int ai_protocol;  协议类型
  size_t ai_addrlen;  地址长度
  char *ai_canoname;  主机名
  struct sockaddr *ai_addr; socket结构体
  struct addrinfo *ai_next; 下一个addinfo
  }
 netdb.h
 struct hostent *gethostbyname(cosnt char *hostname)
 string gethostbyaddr(string ip_address)
 int getaddrinfo(const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result)
           hostname:主机名 service:服务端口号  hints:服务线索  result:返回结果
         Example: struct addrinfo hints,*res=NULL;
      hints.ai_family=PF_UNSPEC;
      hints.ai_socktype=SOCK_DGRAM;
      hints.ai_protocol=IPPROTO_UDP;
      rc=getaddrinfo("127.168.0.189","123",&hints,&res);          

5,socket操作的基本函数
 sys/socket.h
 int socket( int family, int type, int protocol )
  AF_INET; IPv4协议
  AF_INET6; IPv6协议
  AF_LOCAL; UNIX域协议
  AF_ROUTE; 路由套接字
  AF_KEY; 密钥套接字
  SOCK_STREAM; 字接流套接字
  SOCK_DGRAM; 数据报套接字
  SOCK_RAW; 原始套接字
 int bind( int sockfd, struct sockaddr *my_addr, int addrlen )
 int listen( int sockfd, int backlog )
 int accept( int sockfd, struct sockaddr *addr, socklen_t *addrlen )
 int connect( int sockfd, struct sockaddr *serv_addr, int addrlen )
 int send( int sockfd, const void *msg, int len, int flags )
 int recv( int sockfd, void *buf, int len, unsigned int flags )
 int sendto( int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen )
 int recvfrom( int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen )
  flags一般为0

6,实例:
 TCP使用的模型:     USER        SERVER
       socket->bind socket->bind->listen
        connect       ->       accept
       send/sendto    ->    recv/recvfrom  
       recv/recvfrom  <- send/sendto
     close   close
 
五,文件I/O
Stream I/O
 sys/stat.h,fcntl.h,unistd.h
 int open( const char *pathname, flags, int perms )
     flags: O_RDONLY|O_WRONLY|O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_TRUNC|O+APPEND
     perms: 0600
 int close( int fd )
 ssize_t read( int fd, void *buf, size_t count )
 ssize_t write( int fd, void *buf, size_t count )
 off_t lseek( int fd, off_t offset, int whence )
 int fcntl( int fd, int cmd, struct flock *lock )
    cmd: F_DUPFD Copy file
     F_GETFD Get close-on-execute mark
     F_SETFD Set close-on-excute mark
     F_GETFL Get open flag
     F_SETFL Set open flag
     F_GETFK Get lock
     F_SETFK Set lock
     F_SETLKW Set lock and wait
     F_GETOWN Get SIGIO and SIGURG's pid
     F_SETOWN Set the file's pid
 struct flock{  to sovle file share
  short l_type;  F_RDLCK,F_WRLCK,F_UNLCK
  off_t l_start; Compare position
  short l_whence; SEEK_SET,SEEK_CUR,SEEK_END
  off_t l_len;
  pid_t l_pid;
 }
 FILE I/O type:
  1,Block
  2,Non-block
  3,I/O switch
  4,Signal driver
  5,Non-sync I/O
 sys/types.h,sys/time.h,unistd.h
 int select( int numfds, fd_set *readfds, fd_set *writefds, fd_set *exeptfds, struct timeval *timeval )
  numfds: the file's max number+1
  readfds:the set of read files
  writefds:the set of write files
  exeptfds:the set of exept files
  timeout: NULL;wait always
     VALUE;some time
     0:never wait
 FD_ZERO( fd_set *set )
 FD_SET( int fd, fd_set *set )
 FD_CLR( int fd, fd_set *set )
 FD_ISSET( int fd, fd_set *set )
TEXT FILE I/O
 stdio.h
 FILE *fopen( const char *path, const char *mode )
 FILE *fdopen( itn fd, const char *mode )
 FILE *freopen( const char *path, const char *mode, FILE *stream )
 int fclose( FILE *stream )
 size_t fread( void *ptr, size_t size, size_t nmemb, FILE *stream )
 size_t fwrite( const void *ptr, size_t size, size_t nmemb, FILE *stream )
 int getc( FILE *stream )
 int fgetc( FILE * stream )
 int getchar( void )
 int putc( FILE *stream )
 int fputc( FILE *stream )
 int putchar( int c )

 char *gets( char *s )
 char fgets( char *s, int size, FILE *stream )
 int puts( const char *s )
 int fputs( const char *s, FILE *stream )

 int scanf( const char *format, ... )
 int fscan( FILE *fp, const char *format, ... )
 int sscanf( char *buf, const char *format, ... )
 int printf( const char *format,... )
 int fprintf( FILE *fp, const char *format, ... )
 int sprintf( char *buf, const char *format, ... )


 
 

 

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值