线程操作基础

1.线程基本函数
    1)线程创建
        原型:
            int pthread_create(pthred_t *restrict tidp, const pthread_attr_t *restrict_attr, void* (*start_rtn)(void*), void *restrict arg);
    
        作用:
            创建一个新线程。
    
        参数:
            restrict tidp:返回一个线程ID值。
            restrict_attr:传入线程属性设置。
            start_rtn:新线程函数。
            restrict arg:传入线程指针
    
        返回值:
            成功返回0,失败返回错误码。
    
    2)线程分离
        原型:
            int pthread_detach(pthread_t pthread);
    
        作用:
            线程有可结合的或分离的两种状态,默认情况下为可结合的。一个可结合的线程可以被其他线程回收资源或杀死,在被其他线程回收之前,资源不被释放。
            分离状态相反,不能被其他线程回收资源或杀死。直到分离线程结束时,由系统自动释放。
            该函数用于分离线程。
        
        参数:
            pthread:线程ID
            
        返回值:
            成功返回0,失败返回错误码。
    
    3)线程终止信号
        原型:
            int pthread_cancel(phtread_t pthread);
        
        作用:
            发送终止信号给线程。
    
        参数:
            pthread:线程ID
    
        返回值:
            成功返回0,否则非0。发送成功并不代表线程pthread会终止。
        
        相关函数:
            线程的默认状态为:PTHREAD_CANCEL_ENABLE和PTHREAD_CANCEL_DEFERRED
            这三个函数用来设置是否可以被其他线程调用pthread_cancel函数取消或终止。
            pthread_setcancelstate();
            作用:
                用来设置当前线程的“可取消性”状态,并且将先前的状态返回到oldstate引用中。
                “可取消性”状态的合法值分别是:PTHREAD_CANCEL_ENABLE 和 PTHREAD_CANCEL_DISABLE。
                这个函数还可以查询当前线程的“可取消性”状态,即把第一个参数设为NULL。
            pthread_setcanceltype();
            作用:
                用来设置当前线程的“可取消类型”,并且将先前的类型返回到oldtype引用中。
                “可取消类型”的合法值分别是:
                    PTHREAD_CANCEL_DEFERRED :线程接收到取消操作后,直到运行到“可取消点”后取消。
                    PTHREAD_CANCEL_ASYNCHRONOUS :线程接收到取消操作后,立即取消。
            phtread_testcancel();
            作用:
                用来在当前线程创建一个“可取消点”。如果当前线程是不能取消的,则这个函数无效。
                若可取消,则在收到终止信号时,在此位置退出线程。
            
        参考资料:        
            http://blog.csdn.net/i_am_jojo/article/details/7594174
            http://blog.csdn.net/zy799894671/article/details/18008267

    4)等待线程结束信号
        原型:
            int pthread_join(pthread_t pthread, void **retval);
        作用:
            用来等待一个线程的结束,线程间同步的操作
    
        参数:
            pthread:线程ID
            retval:用来存储被等待线程的返回值
    
        返回值:
            成功返回0,失败返回错误码。
            
    5)线程结束
        原型:
            void pthread_exit(void *retval);
            
        作用:
            结束线程。
            
        参数:
            retval可由其他线程调用pthread_join获取。
        
        返回值:
            无。
            
    6)线程属性设置
        线程属性函数参考资料:
            http://blog.csdn.net/zsf8701/article/details/7843837
    
    7)其他相关函数
        pthread_t pthread_self(void);
            获取当前线程ID
        int pthread_equal(pthread_t thread1, pthread_t thread2);
            比较两个线程是否为同一个
    
    
2.线程同步
    互斥量:
    1)初始化
        宏初始化:
            pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
        函数初始化:
        原型:
            int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
        
        作用:
            初始化互斥量
            
        参数:
            restrict mutex:互斥量结构指针
            restrict attr:线程属性指针
        
        返回值:
            成功返回0,失败返回错误码。
            
    2)加锁
        原型:
            int pthread_mutex_lock(pthread_mutex_t *mutex);
        
        作用:
            加锁。
            
        参数:
            mutex:互斥量结构指针
        
        返回值:
            成功返回0,失败返回错误码。
        
        相关函数:
            int pthread_mutex_trylock(pthread_mutex_t *mutex);
            得不到锁会立即返回,并返回EBUSY错误。
            int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abs_timeout);
            会等待abs_timeout时间,得不到锁返回ETIMEDOUT错误。
            
    4)解锁
        原型:
            int pthread_mutex_unlock(pthread_mutex_t *mutex);
        
        作用:
            解锁
            
        参数:
            mutex:互斥量结构指针
        
        返回值:
            成功返回0,失败返回错误码。
            
    5)释放锁
        原型:
            int pthread_mutex_destroy(pthread_mutex_t *mutex);
            
        作用:
            释放锁资源。
            
        参数:
            mutex:互斥量结构指针
        
        返回值:
            成功返回0,失败返回错误码。
    
    6)互斥量属性设置
        相关函数:
            int pthread_mutexattr_init(pthread_mutexattr_t *attr);
            int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
            用来获取和设置互斥量是否被进程共享属性:
            如果属性设置为PTHREAD_PROCESS_SHARED,那么从多个进程共享的内存区域中分配的互斥量就可以用于这些进程的同步。
            如果属性设置为PTHREAD_PROCESS_PRIVATE,那么互斥量只能用于一个进程中的多个线程同步。这个是默认的属性。
            int pthread_mutexattr_getpshared(const pthread_mutexattr_t * restrict attr, int *restrict pshared);
            int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared);
            
        参考资料:
            http://blog.csdn.net/linux_ever/article/details/51039706
    
    参考资料:
        http://www.cnblogs.com/yuuyuu/p/5140251.html
        
    条件变量
    1)初始化
        宏初始化:
            pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
        函数初始化:
            int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
    
    2)等待或通知条件变量
            int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);
            int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
    
            int pthread_cond_broadcast(pthread_cond_t *cond);
            int pthread_cond_signal(pthread_cond_t *cond);
            
    3)释放条件变量
            int pthread_cond_destroy(pthread_cond_t *cond);
            
    参考资料:
        http://www.cnblogs.com/yuuyuu/p/5140875.html
        
    信号量
    1)初始化
        原型:
            int sem_init(sem_t *sem, int pshared, unsigned int value);  
    
    2)减少信号量值
        原型:
            int sem_wait(sem_t *sem);  
                
    3)增加信号量值
        原型:
            int sem_post(sem_t *sem);  
    
    4)销毁
        原型:
            int sem_destroy(sem_t *sem);  
    
    其他线程同步方法:
        读写锁、自旋锁。
    
3.信号
    1)signal();
    2)kill();
    3)pthread_kill();
    
    参考资料:
        http://blog.csdn.net/heyustudent/article/details/17506839

4.问题
1)为什么在子线程中无限循环,主线程pthread_cancel发送终止子线程信号,子线程不能结束掉?
    原因:
        这是因为子线程一直在while()循环,没有挂起,所以不能将其取消。
    解决办法:
        在子线程中用pthread_testcancel函数,设置线程取消点,并且要设置线程的状态为可取消和执行到取消点才取消。
        或者让其挂起,如:sleep

2)Linux下消息队列实现
    使用条件变量+互斥锁
    流程:
        入队列线程中。将数据push入队列中,并用pthread_cond_signal发送条件信号。
        出队列线程中。phtread_cond_wait检测到信号被唤醒,从队列中pop出数据。
        在出入队列时,都需要加上互斥锁。
        
3)多线程下gdb如何调试


4)协程的作用和意义




        
       

猜你喜欢

转载自blog.csdn.net/u012654882/article/details/61648887