TheOneAC

init


  • Home

  • Categories

  • Archives

  • Tags

TCP协议簇

Posted on 2016-10-25

part 1

物理层
  • 比特流传输
  • 比特同步、物理拓扑
  • 传输方式:半双工、双工
    数据链路层
  • 节点间帧传输
  • 组帧
  • 加入物理地址
  • 流量控制:发送速度小于接受速度
  • 接入控制:决定链路控制权
  • 确保组网内部节点间传递
    网络层
  • 确保源点到终点间的分组交付
  • 路由选择
  • 点点交付
    传输层
  • 报文源点到终点的端端交付
  • 分段与重装
    会话层
  • 会话控制与同步
    表示层
  • 编码转换
  • 信息加密与压缩
    应用层
  • 虚拟终端
  • 文件传输与管理
  • 邮件服务和名录服务
    图2.14
  • 以太网数据帧长46~1500字节
  • 隐蔽站问题:先发一个请求服务帧(RTS),请求服务时间,接收站广播(CTS)在服务时间内只为请求站服务
  • 中继器:连接同一子网的不同网段
  • 集线器:多端口转发
  • 网桥:工作在链路层,检查MAC地址,过滤帧转发地址
  • 透明网桥: 帧转发,自学习,避免环路
  • 路由器转发会修改物理地址,工作在网络层,
    • 整个传递过程目的IP地址不变
    • 路由器接受前,目的物理地址是路由器地址
    • 接收后转发,源物理地址是路由器物理地址
      1
      2
      3
      4
      5
      网络地址:主机位全0
      直接广播地址:主机位全1
      受限广播地址:全1
      这个网络这个主机:全0
      这个网络特定主机:网络位全0

路由表

  • 目的网络地址:使用特定网络地址转发
  • 下一跳地址:直接交付时为空
  • 接口位置:定义转发接口
  • 目的地址查找成功,ARP映射获得物理地址,帧转发到下一跳
            OP 源MAC 源IP 目的MAC 目的IP
    ARP请求: 1  *      *            *
    ARP响应: 2  *      *     *      *
    RARP请求: 3  *
    RARP响应: 4  *      *     *      *
    
    图8.10IP选项格式
    IP报文总长20~65535,首部长:20~60字节
    总长以1字为单位,首部 长以4字节为单位
    分片偏移以8字为单位,相对于原始数据包起点
  • IP协议字段:1 ICMP 2 IGMP 6 TCP 17:UDP 89 OSPF
    图9.1ICMP报文类型
  • 差错报文发送给原始数据源
  • 对差错报文不再发送差多报文
  • 对多播报文不发送差错报文
  • 分片数据报的非首片不发送差错报文
  • 特殊地址数据报不发送差错报文
    每一个因为拥塞丢弃的报文都向源点发送源点抑制报文
    ICMP协议为IP协议提供:
  • 差错报告、差错控制(重点不可达,超时、源点抑制、参数问题、改变路由)、
  • 主机管理查询(回送送请求和响应、时间戳请求与响应)、
  • 流量控制(源点抑制报文)服务

发送超时报文:

  • (路由器发送)收到的报文TTL字段为0,
  • (目的主机发送)规定时间内未收到报文的某个分片
    改变路由报文:路由器向主机发送改变路由报文
    回送请求和回送回答报文用于测试主机可达性确认网络层通信是否正常
    时间戳请求与回答:确认往返时间,机器间时间同步
    ping利用回送请求与响应报文实现
    traceroute利用超时报文(中间TTL减少至0,路由器发回超时)和终点不可达报文(UDP端口异常)
  • ICMP 报文类型:查询、成员关系报告、推出报告
  • 成员关系报告需要连续发送两次
  • 成员关系报告:加入组
  • 退出报告:退出一个组
  • 一般性查询:多播路由器周期性发送以监视成员关系
  • 延迟响应:主机等待随机时间,该时间内若有成员关系报告广播,就不再对这个组发送成员关系响应广播
    携带ICMP报文的IP报文中:协议字段为2,TTL必须是1(局域网内)
    目的IP地址:查询(多播):224.0.0.1,成员关系报告(广播):这个组的多播地址,退出报告(多播):224.0.0.2
    ####### 数据链路层MAC地址映射:
  • 多播路由器提取D类IP地址的低23位插入以太网多播地址中
  • D类IP地址组标识共28位,取23位映射以太网多播地址,位未使用,32->1
  • 以太网多播地址范围:01:00:5E:00:00:00 ~ 01:00:5E:7F:FF:FF
  • 广域网不支持物理多播地址,只能采用隧道技术,封装成单播,到达局域网后解析成多播
    ####### UDP
    熟知端口号:0~1023,注册端口号:1024~49151,动态端口号:49152~65535
    UDP长度 = IP长度-IP首部长度
    TCP
  • 编号从随机数开始
  • 报文序号:首字节序号
  • 确认号:期望接收的下一个序号
  • SYN 和SYN+ACK报文不携带数据,消耗一个序号
  • ACK不携带数据则不消耗序号
    12.9
    12.11
  • FIN不消耗序号,FIN+ACK只消耗一个序号

APUE Process

Posted on 2016-10-10   |   In Process
chapter seven
  • Process tremination

    • Return from main
    • Calling exit
    • Calling _exit or _Exit
    • Return of the last thread from its start routine
    • Calling pthread_exit
    • from the last thread
    • Abnormal termination occurs in three ways:
      • Calling abort (Section 10.17)
      • Receipt of a signal (Section 10.2)
      • Response of the last thread to a cancellation request
  • Exit Functions

    1
    2
    3
    4
    5
    #include <stdlib.h>
    void exit(int status);
    void _Exit(int status);
    #include <unistd.h>
    void _exit(int status);

_exit and _Exit, which return to the kernel immediately, and exit, which performs certain cleanup processingand then returns to the kernel.

  • atexit()
    1
    2
    3
    #include <stdlib.h>
    int atexit(void (*func)(void));
    Returns: 0 if OK, nonzero on error
  • a process can register at least 32 functions that are automatically called by exit. These are called exit handlers and are registered by calling the atexit function.
  • The exit function calls these functions in reverse order of their registration.
  • Each function is called as many times as it was registered.
  • Environment List
    Environment
    the environment strings are typically stored at the top
    of a process’s memory space, above the stack.
chapter eight
  • pid_t
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <unistd.h>
    pid_t getpid(void);
    Returns: process ID of calling process
    pid_t getppid(void);
    Returns: parent process ID of calling process
    uid_t getuid(void);
    Returns: real user ID of calling process
    uid_t geteuid(void);
    Returns: effective user ID of calling process
    gid_t getgid(void);
    Returns: real group ID of calling process
    gid_t getegid(void);
    Returns: effective group ID of calling process

fork

- 调用一次,返回两次,子进程返回0, 父进程返回子线程pid
- 子进程只保留调用fork 的线程副本
- 父进程中所有打开的文件描述符被复制到子进程
- 子进程不集成父进程的文件锁,未处理闹钟清除,未处理信号集置空
- 父进程先于子进程结束,子进程被init进程收养,其父进程ID为1
- 已经结束但未被父进程处理的进程:僵死进程

wait waitpid

1
2
3
4
#include <sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
Both return: process ID if OK, 0 (see later), or −1 on error
  • wait or waitpid do
    • Block, if all of its children are still running
    • Return immediately with the termination status of a child, if a child has terminated and is waiting for its termination status to be fetched
    • Return immediately with an error, if it doesn’t have any child processes
  • OSIX.1 waitpid function.
    The interpretation of the pid argument for waitpid depends on its value:
  • pid == −1 Waits for any child process. In this respect, waitpid is equivalent to wait.
  • pid > 0 Waits for the child whose process ID equals pid.
  • pid == 0 Waits for any child whose process group ID equals that of the calling process.
  • pid < −1 Waits for any child whose process group ID equals the absolute value of pid

exec

1
2
3
4
5
6
7
8
9
10
#include <unistd.h>
int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ );
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg0, ...
/* (char *)0, char *const envp[] */ );
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execlp(const char *filename, const char *arg0, ... /* (char *)0 */ );
int execvp(const char *filename, char *const argv[]);
int fexecve(int fd, char *const argv[], char *const envp[]);
All seven return: −1 on error, no return on success

l stands for list, v stands for vector, e stands for environment
The functions execl, execlp, and execle require each of the command-line arguments to the new program to be specified as separate arguments. We mark the end of the arguments with a null pointer.
For the other four functions (execv, execvp, execve, and fexecve), build an array of pointers to the arguments, and the address of this array pass to these three functions.
exec

Process schedule

1
2
3
4
5
6
7
8
#include <unistd.h>
int nice(int incr);
#include <sys/resource.h>
int getpriority(int which, id_t who);
Returns: new nice value − NZERO if OK, −1 on error
#include <sys/resource.h>
int setpriority(int which, id_t who, int value);
Returns: 0 if OK, −1 on error

which : PRO_PROCESS , PRO_GROUP, PRO_USER

Network programming csapp

Posted on 2016-10-10   |   In Network Programming
  • IP 地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    struct in_addr{
    unsigned int s_addr
    }
    #include <netinet/in.h>
    unsigned long int htonl(unsigned long int hostlong);
    unsigned short int htons(unsigned short int hostshort);
    本地转网络字节序
    unsigned long int ntohl(unsigned long int hostlong);
    unsigned short int ntohs(unsigned short int hostlong);
    网络转本地字节
    均以无符号数转换
    网络字节摩恩为:大端,即有效地位存放在地址高位
    #include<arpa/inet.h>
    int inet_aton((const char*cp, struct in_addr *inp);
    点分十进制串(cp)转网络字节序IP(inp)
    int inet_ntoa (struct in_addr in);
    网络字节序IP 转点分十进制
  • Domain structure

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <netdb.h>
    struct host{
    char *h_name; // domain name
    char **h_aliases; // Null-terminated array of domain names
    int h_addrtype; // host type (AF_INET)
    int h_length; // length of addr in bytes
    char **h_addr_list; // Null-terminated array of in_addr strcuts
    }
    struct hostent * gethostbyname(const char* name);
    strcut hostent *gethostbtaddr(const char* addr,
    int len(sizeof(addr)),int type(AF_INET))
    success none -null return, else set h_errno
  • Socket structure

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include<netinet/in.h>
    struct sockaddr{
    unsigned short sin_family; // address falily (AF_INET)
    char sa_data[14]; // address data
    };
    struct sockaddr_in{
    unsigned short sin_family;// AF_INET
    unsigned short sin_port; // port number
    unsigned short sin_addr; // IP address
    unsigned char sin_zero[8] // pad
    }
  • Socket function

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include <sys/typs.h>
    #include <sys/socket.h>
    int socket(inr domain, SOCK_TREAM, int protoctol);
    成功非负,失败-1
    常规调用 : clinetfd = socket(AF_INET,SOCK_STREAM,0);
    int connect(int sockfd, struct sockaddr * server_addr, int addrlen);
    成功0,失败-1
    connect函数与套接字地址为serv_addr服务器连接,阻塞直到连接成功
    int bind(int sockfd, struct *my_addr, int len);
    success 0,eles -1
    将my_addr服务器套接字地址与套接字描述符sockfd绑定,addrlen = sizeof(sockaddr_in);
    int listen(int sockfd, int backlog);
    成功0,失败-1
    将sockfd从主动套接字转为监听套接字,backlog 设置拒绝连接前的等待队列请求数量
    int accept(int listenfd, struct sockaddr *adr, int * addrlen);
    成功非负,失败-1
    等待到达侦听描述符sockfd的连接请求,将客户端套接字地址写入addr, 并返回已链接符
  • 数据传输
  • send
    1
    2
    3
    4
    5
    #include <sys/socket.h>
    ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);
    ssize_t sendto(int sockfd, const void *buf, size_t nbytes, int flags, const struct sockaddr *destaddr, socklen_t destlen);
    ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    Returns: number of bytes sent if OK, −1 on error

sendto 可在无连接端口上指定目标地址

  • receive
    1
    2
    3
    ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
    ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flags, struct sockaddr *restrict addr, socklen_t *restrict addrlen);
    ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

APUE Sockets

Posted on 2016-10-09   |   In Sockets
  • Socket Descriptors
    1
    2
    3
    #include <sys/socket.h>
    int socket(int domain, int type, int protocol);
    Returns: file (socket) descriptor if OK, −1 on error


1
2
3
#include <sys/socket.h>
int shutdown(int sockfd, int how);
Returns: 0 if OK, −1 on error

how : SHUT_RD SHUT_WR SHOT_RDWR

  • Byte Ordering
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <arpa/inet.h>
    uint32_t htonl(uint32_t hostint32);
    $ Returns: 32-bit integer in network byte order
    uint16_t htons(uint16_t hostint16);
    $ Returns: 16-bit integer in network byte order
    uint32_t ntohl(uint32_t netint32);
    $ Returns: 32-bit integer in host byte order
    uint16_t ntohs(uint16_t netint16);
    $ Returns: 16-bit integer in host byte order
  • translate btween binary and text
    1
    2
    3
    4
    5
    6
    7
    #include <arpa/inet.h>
    const char *inet_ntop(int domain, const void *restrict addr,
    char *restrict str, socklen_t size);
    Returns: pointer to address string on success, NULL on error
    int inet_pton(int domain, const char *restrict str,
    void *restrict addr);
    Returns: 1 on success, 0 if the format is invalid, or −1 on error

dimain : AF_INET, AF_INET6
-

APUE Threads

Posted on 2016-10-09   |   In Threads
  • A thread ID is represented by the pthread_t data type. Implementations are allowed to use a structure to represent the pthread_t data type

    1
    2
    3
    #include <pthread.h>
    int pthread_equal(pthread_t tid1, pthread_t tid2);
    Returns: nonzero if equal, 0 otherwise
  • A thread can obtain its own thread ID by calling the pthread_self function.

    1
    2
    pthread_t pthread_self(void);
    Returns: the thread ID of the calling thread
  • Thread Creation

    1
    2
    3
    4
    int pthread_create(pthread_t *restrict tidp,
    const pthread_attr_t *restrict attr,
    void *(*start_rtn)(void *), void *restrict arg);
    Returns: 0 if OK, error number on failure

Note that the pthread functions usually return an error code when they fail. They don’t set errno like the other POSIX functions.

  • Thread Termination
    A single thread can exit in three ways, thereby stopping its flow of control, without terminating the entire process.
  1. return from the start routine. The return value is the thread’s exit code.
  2. be canceled by another thread in the same process.
  3. pthread_exit.
    1
    2
    3
    void pthread_exit(void *rval_ptr);
    int pthread_join(pthread_t thread, void **rval_ptr);
    Returns: 0 if OK, error number on failure
  • pthread_cancel: One thread cancel another in the same process

    pthread_cancel doesn’t wait for the thread to terminate; it merely makes the request.

    1
    2
    3
    int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,
    const struct timespec *restrict tsptr);
    Returns: 0 if OK, error number on failure

the timeout value is reached, pthread_mutex_timedlock will return the error code ETIMEDOUT without locking the mutex.

  • Reader–Writer Locks
    hare in read, exclusive in write
    1
    2
    3
    4
    5
    6
    7
    int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,
    const pthread_rwlockattr_t *restrict attr);
    int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
    int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
    int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
    All return: 0 if OK, error number on failure
  • Cond_wait

    1
    2
    3
    4
    #include <pthread.h>
    int pthread_cond_signal(pthread_cond_t *cond);
    int pthread_cond_broadcast(pthread_cond_t *cond);
    Both return: 0 if OK, error number on failure
  • Cancel

    1
    2
    3
    4
    5
    6
    #include <pthread.h>
    int pthread_setcancelstate(int state, int *oldstate);
    $ state : PTHREAD_CANCEL_ENABLE/ PTHREAD_CANCEL_DISABLE
    int pthread_setcanceltype(int type, int *oldtype);
    # type : PTHREADCANCEL_DEFERRED / PTHREADCANCEL_ASYNCHRONOUS
    Returns: 0 if OK, error number on failure
  • Signal

    1
    2
    3
    4
    5
    #include <semaphore.h>
    int sem_init(sem_t *sem, 0, unsigned int value);
    int sem_wait(sem_t *s)//P
    int sem_post(sem_t *s)//V
    success return 0, else -1
  • 线程安全

    不安全函数类

    1. 不保护共享变量
    2. 保持跨越多个调用状态的函数 :非原子操作
    3. 返回指向静态变量指针的函数 :某个线程的返回覆盖其他线程的调用
    4. 调用线程部不安全函数
      • 调用2类线程一定不安全,只能重写保证线程安全
      • 调用1,3类时,用互斥所保护共享变量则线程安全
    • reentrant funtion : never change any shared-variables.
    • reentrant funtion is a subset of thread-safe funtion
    • some thread-safe funtion may be not reentrant.

    none-thread-safe library funtions

    • rand
    • strtok
    • asctime
    • ctime
    • gethostbyaddr/gethostbyname
    • int_ntoa
    • locatime

    互斥锁加锁,同时占用s,t两个锁的线程必须以相同顺序给s,t加锁

Programming With POSIX Threads

Posted on 2016-10-01

Chapter One

  • Asynchronous: two operation proceed independently of each other.
  • thread: just a more way to make application asynchronous
  • concurency does not imply that the operations proceed simultaneously
  • concurrency allows application to take adcantage of asynchronous capabilities and “do work” while independent operations are proceeding.
  • 并发的实质是一个物理CPU(也可以多个物理CPU) 在若干道程序之间多路复用,并发性是对有限物理资源强制行使多用户共享以提高效率。
  • 并行性指两个或两个以上事件或活动在同一时刻发生。在多道程序环境下,并行性使多个程序同一时刻可在不同CPU上同时执行。
  • Reentrant code should avoid relying on static data and, ideally, should avoid reliance on any form of synchronization between threads.
  • A system’s scheduling facility may allow each thread to run until it voluntarily yields the processor to another thread ("run until block").
  • It may provide time-slicing, where each thread is forced to periodically yield so that other threads may run `(“round-robin”)
  • A thread may have o processor status and coprocessor control registers.
  • A thread does not include most of the rest of the state associated with a process;
  • threads do not have their own file descriptors or address space.

gcc thread.c -o thread -lpthread

  • For very simple applications ,an event-based implementation may be simpler than the multiprocess or multithread variations

  • Some advantages of the multithreaded programming model follow:

    1. Exploitation of program parallelism on multiprocessor hardware. Parallelism is the only benefit that requires special hardware. The others can help most programs without specialhardware.
    2. More efficient exploitation of a program’s natural concurrency, by allowing the programto perform computations while waiting for slow I/O operations to complete.
    3. A modular programming model that clearly expresses relationships between independent “events” within the program. These advantages are detailed in the following sections.
  • It is easy to lose performance by using too much synchronization;

  • The performance suffers when the multithreaded implementation adds threadsynchronization and scheduling overhead to the work you are to accomplish.
  • Your most powerful and portable thread debugging tool is your mind

Chapter Two

1
2
3
4
5
6
7
8
9
10
11
pthread_t thread;
int pthread_equal (pthread_t t1, pthread_t t2);
//compare two thread identifiers
int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start)(void *),void *arg);
pthread_t pthread_self (void);
//get its own identifier using the pthread\_self function
//returns a nonzero value if refer to the same thread, 0 if not the same
int sched_yield (void);
int pthread_exit (void *value_ptr);
int pthread_detach (pthread_t thread);
int pthread_join (pthread_t thread, void **value_ptr);
  • The initial thread is special because the process terminates without allowing other threads to complete
  • Detaching a thread tells the system that you no longer need that thread, and allows the system to reclaim the resources allocated to the thread.
  • Returning from main will cause the process to terminate, along with all threads.
  • code the main thread to terminate by calling pthread_exit, which would allow the process to continue until all threads have terminated.

    The most important thing to remember about thread creation is that there is no synchronization between the creating thread’s return from pthread_create and the scheduling of the new thread. That is, the thread may start before the creating thread returns. The thread may even run to completion and terminate before pthread_create returns

  • pthread_join is a convenience, not a rule.

    it is often at least as simple to create the thread detached and devise your own customized return mechanism as it is to use pthread_join. For example, broadcast a condition variable when done.

Chapter Three

  • Critical sections “serial regions” : areas of code that affect a shared state.
  • The most common and general way to synchronize between threads is to ensure that all memory accesses to the same (or related) data are “mutually exclusive.”

  • Creating and destroying a mutex

    1
    2
    3
    pthread_mutex_t mutex = PTHREAD_MUNEX_INITIALIZER;
    int pthread_mutex_init (pthread_mitex_t *mutex, pthread_mutexattr_t *attr);
    int pthread_mutex_destroy (pthread_mutex_t *mutex);
  • never make a copy of a mutex, the result of using a copied mutex is undefined.

  • It is a good idea to associate a mutex clearly with the data it protects, if possible, by keeping the definition of the mutex and data together
  • it is safe (and a good idea) to unlock and destroy the mutex before freeing the storage that the mutex occupies.
  • the mutex dynamically initialized by calling pthread_mutex_init should destroyed by calling pthread_mutex_destroy. but a mutex that was statically initialized using the PTHREAD_MUTEX_INITIALIZER macro not, wihch will be destroyed automatically.
1
2
3
int pthread_mutex_lock (pthread_mutex_t *mutex);
int pthread_mutex_trylock (pthread_mutex_t *mutex);
int pthread_mutex_unlock (pthread_mutex_t *mutex);

pthread_mutex_trylock function will return an error status (EBUSY) instead of blocking if the mutex is already locked.

  • A condition variable wait always returns with the mutex locked
  • The mutex must always be locked when you wait on a condition variable

Creating and destroying a condition variable

1
2
3
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init (pthread_cond_t *cond, pthread_condattr_t *condattr);
int pthread_cond_destroy (pthread_cond_t *cond);

  1. cond_wait 等待信号量,若未收到信号量,解锁mutex,并挂起到相应信号量等待队列原子操作(cond\_wait 不返回处于等待信号量状态,不占用CPU)
  2. 收到信号量,尝试上锁mutex,若锁被占用则等待,直到获得锁,若上锁成功,进入临界区使用条件变量
  3. 由外部unlock完成解锁

Waiting on a condition variable

1
2
int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *expiration);

  • Each condition variable must be associated with a specific mutex, and with a predicate condition.
  • That is, each condition variable must be associated, at any given time, with only one mutex–but a mutex may have any number of condition variables associated with it.

Waking condition variable waiters

1
2
int pthread_cond_signal (pthread_cond_t *cond);
int pthread_cond_broadcast (pthread_cond_t *cond);

Chapter five

  • once initialize
    1
    2
    pthread_once_t once_control = PTHREAD_ONCE_INIT;
    int pthread_once (pthread_once_t *once_control, void(*init_routine) (void));
  • First, you declare a control variable of type pthread_once_t. The control variable must be statically initialized using the PTHREAD_ONCE_INIT macro,
  • You must also create a function containing the code to perform all initialization that is to be associated with the control variable.
  • Now, at any time, a thread may call pthread_once, specifying a pointer to the control variable and a pointer to the associated initialization function.
  • only the first call pthread_once will successfully initialized.
  • Mutex attributes
    1
    2
    3
    4
    5
    6
    7
    pthread_mutexattr_t attr;
    int pthread_mutexattr_init { pthread_mutexattr_t *attr);
    int pthread_mutexattr_destroy (pthread_mutexattr_t *attr);
    \#ifdef _POSIX_THREAD PROCESS SHARED
    int pthread_mutexattr_getpshared (pthread_mutexattr_t  *attr, int *pshared);
    int pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared);
    endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <pthread.h>
#include "errors.h"
pthread_mutex_t mutex;
int main (int argc, char *argv[])
{
pthread_mutexattr_t mutex_attr;
int status;
status = pthread_mutexattr_init (& mutex\_attr);
if (status != 0)
err_abort (status, "Create attr");
#ifdef _POSIX_THREAD_PROCESS_SHARED
status = pthread_mutexattr_setpshared (
& mutex\_attr, PTHREAD_PROCESS_PRIVATE);
if (status != 0)err_abort (status, "Set pshared");
#endif
status = pthread_mutex_init (&mutex, &mutex_attr);
if (status != 0)
err_abort (status, "Init mutex");
return 0;
}
  • Condition variable attributes

    1
    2
    3
    4
    5
    6
    7
    pthread_condattr_t attr;
    int pthread_condattr_init (pthread_condattr_t *attr);
    int pthread_condattr_destroy (pthread_condattr_t *attr);
    #ifdef _POSIX_THREAD_PROCESS_SHARED
    int pthread_condattr_getpshared(pthread_condattr_t *attr, int *pshared);
    int pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared);
    #endif
  • Thread attributes

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    pthread_attr_t attr;
    int pthread_attr_init (pthread_attr_t *attr);
    int pthread_attr_destroy (pthread_attr_t *attr);
    int pthread_attr_getdetachstate (pthread_attr_t *attr, int *detachstate);
    int pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate);
    #ifdef _POSIX_THREAD_ATTR_STACKSISE
    int pthread_attr_getstacksize (pthread_attr_t *attr, size_t *stacksize);
    int pthreae_attr_setstacksize (pthread_attr_t *attr, size_t stacksize);
    #endif
    #ifdef _POSIX_THREAD_ATTR_STACKADDR
    int pthread_attr_getstarkaddr (pthread_attr_t *attr, void *stackaddr);
    int pthread_attr_set-tackaddr (pthread_attr_t *attr, void **stackaddr);
    #endif
  • Cancellation

    1
    2
    3
    4
    5
    6
    int pthread_cancel (pthread_t thread);
    int pthread_setcancelstate (int state, int * oldstate);
    int pthread_setcanceltype (int type, int *oldstate);
    void pthread_testcancel (void);
    void pthread_cleanup_push (void (*routine)(void *), void *arg);
    void pthread_cleanup_pop (int execute);
  • Creating thread-specific data

    1
    2
    3
    pthread_key_t key;
    int pthread_key_create (pthread_key_t *key, void (*destructor)(void *));
    int pthread_key_delete (pthread_key_t key);
  • you should never delete a thread-specific data key until you are sure that no existing threads have a value for that key,
  • Using thread-specific data
1
2
int pthread_setspecific (pthread_key_t key, const void *value);
void *pthread_getspecific (pthread_key_t key);
  • Pthreads will not call the destructor for a thread-specific data key if the terminating thread has a value of NULL for that key.
  • Using destructor functions
    • If your key's value is a pointer to heap memory, you will need to free the memory to avoid a memory leak each time a thread terminates.Pthreads allows you to define a destructor function when you create a thread-specific data key. When a thread terminates with a non-NULL value for a thread-specific data key, the key's destructor (if any) is called with the current value of the key.
    • the order in which destructors are called is undefined. Try to make each destructor as independent as possible.
  • Scheduling policies and priorities
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int sched_get_priority_max (int policy);
    int sched_get_priority_min (int policy);
    int pthread_attr_getinheritsched( const pthread_attr_t *attr, int *inheritsched);
    int pthread_attr_setinheritsched( pthread_attr_t *attr, int inheritsched);
    int pthread_attr_getschedparam (const pthread_attr_t *attr, struct sched_param *param);
    int pthread_attr_setschedparam ( pthread_attr_t *attr, const struct sched_param *param);
    int pthread_attr_getschedpolicy (const pthread_attr_t *attr, int *policy);
    int pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);
    int pthread_getschedparam (pthread_t thread, int *policy, struct sched_param *param);
    int pthread_setschedparam (pthread_t thread; int policy; const struct sched_param *param);
  • When you set the scheduling policy or priority attributes in an attributes object, you must also set the inheritsched attribute!
  • Pthreads does not specify a default value for inheritsched

Priority inversion is when a low-priority thread can prevent a high-priority thread from running

POSIX adjusts to threads

  • fork

    • When a threaded process calls fork to create a child process, Pthreads specifies that only the thread calling fork exists in the child.
    • the thread has the same thread state as in the parent
    • you use fork to clone a threaded program, beware that you may lose access to memory, especially heap memory stored only as thread-specific data values.
    • a mutex was locked at the time of the call to fork, then it is still locked in the child. Because a locked mutex is owned by the thread that locked it, the mutex can be unlocked in the child only if the thread that locked the mutex was the one that called fork. This is important to remember–if another thread has a mutex locked when you call fork, you will lose access to that mutex and any data controlled by that mutex.
  • Avoid using fork inthreaded code except where the child process will immediately exec a new program.

  • Calling pthread_exit from main will terminate the initial thread without affecting the other threads in the process, allowing them to continue and complete normally.

  • flockfile and funlockfile

    1
    2
    3
    void flockfile (FILE *file);
    int ftrylockfile (FILE *file);
    void funlockfile (FILE *file);
  • getchar_unlocked and putchar_unlocked

    1
    2
    3
    4
    int getc_unlocked (FILE *stream);
    int getchar_unlocked (void);
    int putc_unlocked (int c, FILE *stream);
    int putchar_unlocked (int c)

Hints to avoid debugging

  • Never assume that a thread you create will wait for you.
  • Thread inertia is a special case of thread races.
  • thread races that the “loser” generally wins because the memory system will keep the last value written to an address.
  • No ordering exists between threads

  • Scheduling exists to tell the system how important a specific job (thread) is to yourapplication so it can schedule the job you need the most.

  • Synchronization exists to tell the system that no other thread can be allowed into the critical section until the calling thread is done.
  • Cooperate to avoid deadlocks

    One common cause of a deadlock is that some thread has returned from a function without unlocking a mutex

  • Beware of priority inversion
  • Never share condition variables between predicates

    The best solution, when you really want to share a condition variable between predicates, is always to use pthread_cond_broadcast. But when you broadcast, all waiting threads wake up to reevaluate their predicates.

  • Sharing stacks and related memory corrupters

    Having carefully ensured that there is no possible way for the owning thread to pop the stack data while other threads are using the shared data

  • Beware of concurrent serialization
  • Use the right number of mutexes

    A common strategy is to create a separate mutex for each data structure, and use those mutexes to serialize access to the shared data, rather than using the “big mutex” to serialize access to the library.

    • you may decrease the efficiency of the memory system by excessive locking

TCP/IP illustraed V1

Posted on 2016-10-01

IP : unreliable, connectionless datagram delivery service

  • unreliable : when something wrong ,throw away the datagram and try to send ICMP to the source
  • connectionless : each datagram transfered indepently which may get delivered out of order, not maintain any state information about sucessive datagrams
  • network traverse orderisbig endian
  • IP rout search : IP address network ID defaultrouting table
    A complete matching host address is searched for before a matching network ID.

    1
    2
    3
    4
    32-bit IP ----> 48-bit MAC
    | ARP |
    | RARP |
    |<----------------|
  • ARP Cache :maintains the recent mapping from IP to hardware address(MAC)

  • Proxy ARP :a router answer ARP requests on one of its networks for a host on another of its networks
  • Gratuitous ARP:a host sends an ARP request looking for its own IP address

RARP : use the physical address to get the the IP address

  1. RARP request(broadcast), RARP reply (unicast)
  2. RARP request are sen as hardware-level broadcast, not forward by routers.
  3. multiply RARP server are normally provided on a single nework
    all the server replys, but the rquest systerm use the first RARP reply that ir receives.

ICMP

  • ICMP message are transmitted within IP datagrams.
  • chesum cover the entire message
  • ICMP donot response to:
  1. An ICMP error message
  2. A datagram destined to an IP broadcast address.
  3. Datagram sent as a link-layer broadcast.
  4. A fragment other than the first
  5. A datagram whose source address dose not define a single host.

IP route

  • netstat -rn
    U: the route is up;
    G: the route is to differentiate between an indirect route(G) and a direct route
    H : specifies the destination address is a complete host address.
    • indirect route: IP address specify the destination and the link layer address specifies the gateway.
    • direct route : both the IP address and the link-layer address specifies the destinations.

match host -> match subnet -> default gateway

  • The ICMP “host unreachable” error message is sent by a router when it receives an IP datagram that it cannot deliver or forward
  • The ICMP redirect error is sent by a router to the sender of an IP datagram when the datagram should have been sent to a different router

Dynamic route

  • RIP messages are carried in UDP datagrams,port number for RIP is UDP port 520
    RIP in UDP
  1. A stub AS has only a single connection to one other AS. A stub AS carries only local traffic.
  2. A multihomed AS has connections to more than one other AS, but refuses to carry transit traffic.
  3. A transit AS has connections to more than one other AS and is designed, under certain policy restrictions, to carry both local and transit traffic.

BGP uses TCP as its transport protocol, distance vector protocol, but ennumberate the route to each destination

UDP

  • The UDP/TCP checksumcovers the header and the data,but not IP
  • both UDP and TCP include a 12-byte pseudo-header with the UDP datagram (or TCP segment) just for the checksum computation
  • fragmentation : if one fragment is lost the entire datagram must be retransmitted.
  • An IP datagramis the unit of end to end transmission at IP layer ,but a packet is the unit of data passed between the IP layer and the link layer.

Broadcasting and multicasting only apply to UDP

Mapping of a class D IP address into Ethernet multicast address

IGMP

  1. A host sends an IGMP report when the first process joins a group. If multiple processes on a given host join the same group, only one report is sent, the first time a process joins that group. This report is sent out the same interface on which the process joined the group.
  2. A host does not send a report when processes leave a group, even when the last process leaves a group. The host knows that there are no members in a given group, so when it receives the next query (next step), it won’t report the group.
  3. A multicast router sends an IGMP query at regular intervals to see if any hosts still have processes belonging to any groups. The router must send one query out each interface. The group address in the query is 0 since the router expects one response from a host for every group that contains one or more members on that host.
  4. A host responds to an IGMP query by sending one IGMP report for each group that still contains at least one process.
  • an application must convert a hostname to an IP address before it can ask TCP to open a connection or send a datagram using UDP. The TCP/IP protocols within the kernel know nothing about the DNS.
  • TFTP use in UDP
    • each exchange start with the clinet asking the server read a file for the clinet or write a file for the client
    • be used only during the bootstrap process of diskless systems. It uses only a few message formats and a stop-and-wait protocol.
    • he TFTP server provides concurrency by creating a new UDP port for each client.

connection-oriented, reliable, byte stream service

TCP Interactive Data Flow

each interactive keystroke normally generates a datapacket in Rlogin

four segments:

(1) the interactive keystroke from the client,
(2) anacknowledgment of the keystroke from the server,
(3) the echo of the keystroke from the server,
(4)an acknowledgment of the echo from the client.

Nagle algorithm

  • a TCP connection can have only one outstanding small segment that has not yet been acknowledged. No additional small segments can be sent until the acknowledgment is received. Instead, small amounts of data are collected by TCP and sent in a single segment when the acknowledgment arrives.
  • Delayed acknowledgments are used by the receiver of these small segments to see if the acknowledgment can be piggybacked along with data going back to the sender. This often reduces the number of segments, especially for an Rlogin session, where the server is echoing the characters typed at the client.
  • On slower WANs the Nagle algorithm is often used to reduce the number of these small segments. This algorithm limits the sender to a single small packet of unacknowledged data at any time. But there are times when the Nagle algorithm needs to be disabled, and we showed an example of this.
  • flow control is done by the Rlogin client.

SNMP

SNMP uses UDP,a request from the manager may not arrive at the agent, The manager probably wants to implement a timeout and retransmission.
The manager sends its three requests to UDP port 161. The agent sends traps to UDP port 162.

SNMP

SCTP

Posted on 2016-09-23

SCTP : 流传输控制协议

  1. UDP面向报文,保留报文边界,不可靠传输,无流量控制和传输控制
  2. TCP面向字节,不好刘报文边界,可靠传输,拥塞控制和流量控制
  3. 面向报文,可靠传输,拥塞控制流量控制
  4. 位于网络层与应用之间,全双工
  • SCTP 一个关联包含多重流,某一个流堵塞,其他流仍可以交付数据
    • TCP只有一个源IP地址和一个目的IP地址
  • STCP关联支持多重归属服务,正常情况下只有一个路径有效,其他候补;故障时,候补路径补上
  • STCP 允许每一个端使用多个IP地址

  • SCTP使用传输序号TSN对数据块编号,TSN累计编号
  • 流标识符SI区分一个关联内的流
  • 流序号SSN区分同一个流中不同数据块

  • STCP报头定长12字节,序号.确认号.窗口大小放在控制块中
  • 一个分组多个数据块,分属于不同流
  • STCP确认号面向数据块,位于控制信息中,只用来确认数据块
  • 控制块位于数据块之前
  • 通用首部:16位源端口地址,16位目的端口地址,32位验证标志,32位检验和
  • DATA数据块内容只能属于一个数据块,一个报文可以分割为多个数据块

关联建立

1
2
3
4
5
INIT Init tag:1200 rwnd:1000 Init TSN:1000 VT:0
INITACK Init tag:5000 rwnd:2000 Init TSN:1700 VT:1200
COOKIE ECHO cookie VT:5000
COOKIEACK VT:1200
* INIT. INITACK 不携带其他块,COOKIE ECHO. COOKIE ACK 可以携带数据块 `

  • 只有DATA块消耗TSN, DATA 块是唯一可确认的块
    关联终止
    1
    2
    3
    SHUTDOWN VT:x cum :TSN
    SHUTDOWN ACK VT:y
    SHUTDOWN COMPLETE VT:x

TCP/IP

Posted on 2016-09-22   |   In TCP/IP

UDP
TCP head
TCP

APUE File IO

Posted on 2016-09-19   |   In IO

文件描述符

  • 0 : STDIN_FILENO
  • 1 : STDOUT_FILENO
  • 2 : STDERR_FILENO
  • 范围: 0 ~ OPEN_MAX -1
  • open and openat

    1
    2
    3
    4
    #include <fcntl.h>
    int open(const char *path, int oflag, ... /* mode_t mode */ );
    int openat(int fd, const char *path, int oflag, ... /* mode_t mode */ );
    Both return: file descriptor if OK, −1 on error
    • open 和 openat 函数返回当前未用最小文件描述符数值
    • path specifies an absolute path, then open equals to openat
    • path specifier an relative path, The fd parameter is obtained by opening the directory by the relative pathname
  • creat

    1
    2
    3
    #include<fcntl.h>
    int creat (const char *path, mode_t mode);
    Returns: file descriptor opened for write-only if OK, −1 on error

open(path, O_RDWR | O_CREAT | O_TRUNC, mode);

  • close

    1
    2
    3
    #include <unistd.h>
    int close(int fd);
    Returns: 0 if OK, −1 on error
  • lseek

    1
    2
    3
    #include <fcntl.h>
    off_t lseek(int fd, off_t offset, int whence);
    returns: offset if ok, -1 on error

• If whence is SEEK_SET, the file’s offset is set to offset bytes from the beginning of
the file.
• If whence is SEEK_CUR, the file’s offset is set to its current value plus the offset.
The offset can be positive or negative.
• If whence is SEEK_END, the file’s offset is set to the size of the file plus the offset.
The offset can be positive or negative.

  • read/write
    1
    2
    3
    4
    5
    #include <unistd.h>
    ssize_t read(int fd, void *buf, size_t nbytes);
    $ Returns: number of bytes read, 0 if end of file, −1 on error
    ssize_t write(int fd, const void *buf, size_t nbytes);
    $ Returns: number of bytes written if OK, −1 on error

文件共享

文件打开后

  1. 每个进程在进程变种有一个记录项,记录项包含一张文件描述符表(当前进程打开的所有文件)每个文件描述符包含:一个文件描述符标志,一个指向文件表项的指针
  2. 内核为所有打开文件维持一张文件表,每个表项包含:文件状态,当前文件偏移,该文件的v节点表项指针
  3. 每个打开文件都有一个v节点.包含:文件类型,文件操作指针,索引节点等
  4. 每个进程都有自己的文件表项为了维持不同的当前文件偏移量

原子操作

  • 追加:每次都定位到结尾并写入:定位结尾与写入整合为一个原子操作
  • pread/pwrite

    1
    2
    3
    4
    5
    #include <unistd.h>
    ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset);
    Returns: number of bytes read, 0 if end of file, −1 on error
    ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset);
    Returns: number of bytes written if OK, −1 on error
    • 定位与读写操作为一个整体不可中断
    • 不更新当前文件偏移量
  • 创建文件: 检测当前文件是否存在与创建文件整合为一个操作

  • dup/dup2

    1
    2
    3
    4
    #include <unistd.h>
    int dup(int fd);
    int dup2(int fd, int fd2);
    Both return: new file descriptor if OK, −1 on error
    • dup返回当前最小可用文件描述符
    • dup2关闭fd2,若fd == fd2 不关闭直接返回fd2

函数sync,fsync和fdatasync

1
2
3
4
5
#include <unistd.h>
int fsync(int fd);
int fdatasync(int fd);
Returns: 0 if OK, −1 on error
void sync(void);
  • sync修改过区块排入写队列.update守护进程周期性调用flush缓冲区
  • fsync只对fd文件作用,并等待文件写完
  • fdatasync只影响数据部分,同步更新文件属性

函数ioctl

1
2
3
4
5
6
> #include <unistd.h>
#include <sys/ioctl.h>
/* System V */
/* BSD and Linux */
int ioctl(int fd, int request, ...);
Returns: −1 on error, something else if OK

习题/思维导图

1234…6
TheOneAC

TheOneAC

生如逆旅 一苇可航

51 posts
20 categories
33 tags
GitHub Email Quora 知乎
© 2016.7.14 - 2017 TheOneAC
Powered by Hexo
Theme - NexT.Mist