zoukankan      html  css  js  c++  java
  • UDP、线程、mutex锁(day15)

    一、基于UDP的网络编程模型
    服务器端
    1、创建socket.
    2、将fd和服务器的ip地址和端口号绑定
    3、recvfrom阻塞等待接收客户端数据
    4、业务处理
    5、响应客户端
    
    
    客户端:
    1、创建socket
    2、向服务器发送数据sendto
    3、阻塞等待服务器的响应信息
    4、处理响应信息
    5、断开通讯
    
    #include <sys/types.h>
    #include <sys/socket.h>
    ssize_t recvfrom(int sockfd,void *buf,size_t len,
        int flags,
            struct sockaddr *src_addr,
         socklen_t *addrlen);
    功能:从一个socket上接收消息
    参数:
    sockfd:指定socket。socket(2)的返回值
    buf:存放消息的缓冲区地址
    len:指定buf的最大尺寸
    flags:0
    src_addr:存放的是对面的地址
    addrlen:是一个值-结果参数。src_addr的长度
    返回值:
    成功  返回接收到的字节数
    -1  错误  errno被设置
    0    对面down机
    
    #include <sys/types.h>
    #include <sys/socket.h>
    ssize_t sendto(int sockfd, const void *buf, size_t len,         int flags,
                  const struct sockaddr *dest_addr,
             socklen_t addrlen);
    
    功能:在socket上发送消息
    参数:
    sockfd:指定socket
    buf:存放数据的缓冲区首地址
    len:buf中有效的字节数
    flags:0
    dest_addr:目标地址
    addrlen:目标地址的长度
    返回值:
    -1  错误  errno被设置
    成功  返回发送出去的字节数。
    
    编写代码实现基于udp的网络通讯。
    代码参见:
    userv.c   uclie.c
    
    172.30.3.93
    
    网络通讯
    
    二、线程的基础
    线程   执行的基本单位,线程共享进程的资源
    进程   进程是资源分配的基本单位
    
    每个线程有自己的tid。thread_id
    每个线程有自己私有的栈帧。
    
    三、线程的创建
    系统提供了函数pthread_create(3)用于创建线程
    #include <pthread.h>
    int pthread_create(pthread_t *thread, 
            const pthread_attr_t *attr,
                    void *(*start_routine) (void *),
             void *arg);
    功能:创建一个新的线程
    参数:
    thread:存放线程id的缓冲区。
    attr:NULL   缺省属性
    start_routine:线程的执行函数
    arg:start_routine函数的唯一参数。
    返回值:
    0  成功
    错误   错误码
    
    Compile and link with -pthread.
    void *(*start_routine) (void *)
    
    举例说明   创建新的线程
    代码参见  pthread_c.c
    
    getpid(2)获取进程的pid。
    pthread_self(3)来获取线程自己的tid。
    #include <pthread.h>
    pthread_t pthread_self(void);
    功能:获取当前线程的id
    参数:
    void
    返回值:
    返回线程的id。
    
    四、线程退出、汇合、分离
    线程的退出
    1、return和exit(3)的区别
    return只是函数的返回,在线程处理函数中,只是代表了线程的结束。而exit(3)代表的是进程的结束。进程中的所有线程就终止了。
    
    2、使用函数pthread_exit(3)来终止一个线程
    #include <pthread.h>
    void pthread_exit(void *retval);
    功能:终止当前线程
    参数:
    retval:指定传递给另一个线程的值,那个线程调用pthread_join(3)接收这个值。
    
    返回值:
    不返回给调用者。
    3、pthread_cancel(3)
    #include <pthread.h>
    int pthread_cancel(pthread_t thread);
    功能:给线程发送取消请求
    参数:
    thread:指定了接收请求的线程id。
    
    返回值:
    0  成功
    非0   错误码
    
    注意:使用pthread_cancel终止的进程,在使用pthread_join(3)获取线程退出信息的时候,获取到的是PTHREAD_CANCELED。
    
    线程的汇合
    pthread_join(3)等待线程的汇合
    #include <pthread.h>
    int pthread_join(pthread_t thread, void **retval);
    功能:汇合一个终止的线程
    参数:
    thread:指定了等待汇合的线程的id
    retval:
    返回值:
    成功   0
    失败   返回错误码
    
    举例说明  线程的退出和汇合
    代码参见pthread_e.c
    
    线程的分离
    pthread_detach(3)
    #include <pthread.h>
    int pthread_detach(pthread_t thread);
    功能:分离一个线程
    参数:
    thread:指定要分离的线程
    返回值:
    0  成功
    非0   错误码
    
    举例说明  线程的分离
    代码参见 pthread_d.c
    
    新建的线程和进程中已经存在的线程是异步的。
    这些线程会对公共资源形成竞争。怎么解决竞争?
    1、可重入函数
    2、让异步的线程同步的访问共享资源。
    
    五、线程同步  
    条件变量    mutex锁    信号量
    举例说明   多个线程异步访问共享资源(临界资源)
    代码参见   count.c
    
    使用mutex锁解决临界资源的问题
    什么是mutex锁?
    pthread_mutex_t 是一个类型   mutex锁类型
    
    mutex所是一个互斥设备。
    一个mutex锁类型的变量有两中状态
    unlocked:不被任何线程拥有
    locked:被一个线程拥有
    
    一个mutex锁从来不能被两个线程同时拥有。
    如果一个线程想拥有的mutex锁,被另外的线程占用。那么这个线程挂起执行,直到另外线程放弃才能得到。
    
    对临界资源的访问要遵守三歩:
    1、先获取mutex锁
    2、访问临界资源
    3、释放mutex锁
    
    phtread_mutex_init(3)
    #include <pthread.h>
    
    静态初始化一个mutex锁
    pthread_mutex_t  fastmutex=PTHREAD_MUTEX_INITIALIZER;
    
    int  pthread_mutex_init(pthread_mutex_t *mutex,             const  pthread_mutexattr_t *mutexattr);
    功能:初始化一个mutex锁
    参数:
    mutex:指定要初始化的mutex锁
    mutexattr:NULL     默认
    返回值:
    0
    
    int  pthread_mutex_lock(pthread_mutex_t *mutex);
    功能:获取mutex锁,如果这个锁不被其他线程占有,立即返回,拥有了这把锁。将锁的状态改变为locked。
    这把锁被其他线程占有。挂起线程,直到其他线程解锁为止。
    参数:
    mutex:指定了要获取的mutex锁
    返回值:
    非0  错误
    0 成功
    
    
    int  pthread_mutex_trylock(pthread_mutex_t *mutex);
    功能:获取mutex锁,在其他线程占有这个mutex锁的时候,非阻塞。立即返回,错误。EBUSY
    参数:
    mutex:指定要获取的mutex锁
    返回值:
    非0  错误
    0 成功
    int pthread_mutex_unlock(pthread_mutex_t *mutex);
    功能:解锁mutex
    参数:
    mutex:释放mutex锁
    返回值:
    非0  错误
    0 成功
    int pthread_mutex_destroy(pthread_mutex_t *mutex);
    功能:销毁mutex锁
    参数:
    mutex:指定要销毁的mutex锁
    返回值:
    非0  错误
    0 成功
    
    改进count.c。使用mutex锁让进程同步访问临界资源。
    总结:
    一、基于UDP的编程模型
    二、线程的基础
    三、线程的创建
    四、线程的退出、汇合、分离
    五、线程同步   mutex锁
  • 相关阅读:
    使用Enablebuffering多次读取Asp Net Core 请求体
    Windows Forms和WPF在Net Core 3.0框架下并不会支持跨平台
    .Net Core IIS下无Log4Net日志输出,命令行下却有(dotnet运行)
    ElasticSearch7.x Bool查询Java API
    ElasticSearch7.X Java client
    Spark RDD转DataFrame
    spark写mysql
    spark读取mysql
    Spark2.x写Hbase1-2.x
    Spark2.x读Hbase1-2.x
  • 原文地址:https://www.cnblogs.com/Kernel001/p/7732654.html
Copyright © 2011-2022 走看看