zoukankan      html  css  js  c++  java
  • 线程与信号,线程与锁

    #include<stdio.h>
    #include<apue.h>
    #include<pthread.h>
    
    pthread_mutex_t number_mutex  = PTHREAD_MUTEX_INITIALIZER;
    int             globvar  = 0 ;
    
    void *write_p(void *arg){
        while(1){
            pthread_mutex_lock(&number_mutex);
            globvar++;
            printf("the write is %ld
    ",globvar);
            pthread_mutex_unlock(&number_mutex);
            sleep(2);
            
        }
    }
    
    void *read_p(void *arg){
        int temp;
        while(1){
            printf("the read is %ld
    ",pthread_self());
            pthread_mutex_lock(&number_mutex);
            printf("read = %d
    ",globvar);
            sleep(10);
            pthread_mutex_unlock(&number_mutex);
              
        }
    }
    
    int main(){
        pthread_t thid1,thid2;
        int err;
        err = pthread_create(&thid1,NULL,read_p,NULL);
        if(err != 0){
            printf("the pthread is error
    ");
        }
        sleep(1);
        printf("the mid 
    ");
        err = pthread_create(&thid2,NULL,write_p,NULL);
        printf("err is %d
    ",err);
        if(err != 0){
            printf("the pthread is error
    ");
        }
        while(1){
            sleep(1);
        }
       




    #include<stdio.h>
    #include<apue.h>
    #include<pthread.h>
    
    pthread_mutex_t mutex;
    pthread_cond_t    cond ;
    
    void *thread1(void *arg){
        pthread_cleanup_push(pthread_mutex_unlock,&mutex);
        while(1){
            printf("thread1 is runing
    ");
            pthread_mutex_lock(&mutex);
            pthread_cond_wait(&cond,&mutex);
            printf("thread applied the condiation
    ");
            pthread_mutex_unlock(&mutex);
            sleep(4);
        }
        pthread_cleanup_pop(0);
    }
    
    
    
    void *thread2(void *arg)
    {
        while(1){
            printf("thread2 is runing
    ");
            pthread_mutex_lock(&mutex);
            pthread_cond_wait(&cond,&mutex);
            printf("thread2 application is condiation
    ");
            pthread_mutex_unlock(&mutex);
            sleep(1);
        }
    }
    
    
    int main(void){
        
        pthread_t tid1,tid2;
        printf("condiation variable!
    ");
        pthread_mutex_init(&mutex,NULL);
        pthread_cond_init(&cond,NULL);
        pthread_create(&tid1,NULL,thread1,NULL);
        pthread_create(&tid2,NULL,thread2,NULL);
        do{
            pthread_cond_signal(&cond);
            
        }while(1);
    
        sleep(50);
        pthread_exit(0);
        
    }
    


    #include<stdio.h>
    #include<apue.h>
    #include<pthread.h>
    
    int quitflag ;             //退出标志
    sigset_t mask;             //声明一个信号集
    
    pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;            //初始化一个相互排斥锁
    pthread_cond_t waitloc = PTHREAD_COND_INITIALIZER;           //初始化一个条件变量
    
    void * thr_fn(void *arg)                                     //处理信号的线程
    {
        int err;
        int signo;
        while(1){
            err = sigwait(&mask,&signo);                         //解除信号屏蔽字
            if(err != 0){
                printf("errpr
    ");
            }
            switch(signo){                                      //处理不同的信号
                case SIGINT:                                      //处理SIGINT 信号
                    printf("interrupt
    ");
                    break ;
                case SIGQUIT:                                   //处理SIGQUIT 信号
                    pthread_mutex_lock(&lock);                  //上锁
                    quitflag = 1;                               //假设不改变这个标志值。不会调出循环
                    pthread_mutex_unlock(&lock);                //解锁
                    pthread_cond_signal(&waitloc);              //等待条件变量引起唤醒此时堵塞
    
                    printf("case 
    ");
                    return 0;
                default :
                    printf("unexpected signal %d
    ",signo);
                    exit(0);
            }
        }
    }
    
    int main()
    {
        int err;                                                        //标准错误码
        sigset_t oldmask;                                       //声明原先信号集
        pthread_t tid   ;                                       //声明一个线程号
    
        sigemptyset(&mask);                                   //清空信号集
        sigaddset(&mask,SIGINT);                                //加入SIGINT 进信号集
        sigaddset(&mask,SIGQUIT);                               //加入SIGQUIT 进信号集
    
        if((err = pthread_sigmask(SIG_BLOCK,&mask,&oldmask)) != 0) //加入线程信号集主线程開始堵塞这两个信号
            printf("printf SIG_BLOCK is error
    ");
        
        err = pthread_create(&tid,NULL,thr_fn,0);               //创建信号处理线程,新的线程继承了原来的信号屏蔽字
        if(err != 0){
            printf("create is error
    ");
        }
    
        pthread_mutex_lock(&lock);                                   //加锁
        while(quitflag == 0){                 
            printf("ust 
    ");
            pthread_cond_wait(&waitloc,&lock);
        }
        pthread_mutex_unlock(&lock);
        printf("like may be
    ");
        quitflag = 0;
        printf("change the quitflag
    ");
        if(sigprocmask(SIG_SETMASK,&oldmask,NULL) < 0)    //建议完毕工作后将线程屏蔽字还原
            printf("SIG_MASK error");
        exit(0);
    }
    

    线程内相互排斥快的原因:
        线程的全部资源都在线程空间内。寻址仅仅在本线程内部
        进程的消息队列和共享内存会被线程採用==>共享内存最大长处:独立于全部进程
        当程序出错时。共享内存会中的数据会保存在内存中。重新启动后会恢复执行状态。
        消息队列:独立进程和线程,消息必定会被接收而且会被处理(除非是流水线
        作业式)自己能够返回。

    接收到消息的线程和进程挨个运行受到消息的处理程序
        多任务优势:同一时候执行内核处理——单核分时处理
        线程的生命不独立


    进程比线程慢的原因:
        1)进程空间独立。须要内核作为中转
        2)线程在同一进程空间内,寻址内存连续,全部资源在同一进程区间


    CUP内核使用率超过100%的原因:
        多核处理。每一个CPU的使用率相加则使用率超过100%


    线程同步:相互排斥


    相互排斥量的种类:
        相互排斥量 = 线程锁 = mutex
        线程锁,读写锁,自旋锁,条件变量 <==> 线程同步的方式
        @线程锁子类:1)普通锁 2)默认锁 3)快速锁 4)错误校验锁 5)回环锁
         锁用来异步
         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。则会失败,不能锁住相互排斥量
         返回EBUSY。调用该函数防止死锁。
        @线程锁堆的初始化
         有锁就有线程。锁是为线程准备的。


         若不初始化。则锁为上锁状态,无法使用。
         int pthread_mutex_destroy(pthread_mutex_t *mutex);
         int pthread_mutex_init(pthread_mutex_t *restrict mutex,
                                const pthread_mutexattr_t *restrict attr);
         pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
         初始化的两种方式:
         1)动态:int pthread_mutex_init
         2)静态:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
         若初始化为默认属性,则attr置值为NULL;
         若对静态分配相互排斥量,则把它置为常量PTHREAD_MUTEX_INITIALIZER
        @线程锁的使用:先加锁。再使用,再解锁。
        @以前拥有锁的人解锁后不sleep的情况下再次拥有锁的机会更大;若解锁后睡眠,
         则再次抢到锁的机会就均匀了。


         有sleep时,延长了持锁人持锁的时间。本质上是别的线程有了等待的时机。
         导致持锁人解锁之后再次持锁的时间变短了。


        @10秒内检測是否死锁:
         gdb中bt參数查看栈帧,查看方法:
         1)查看进程号 a) gdb attach id(进程号)
                       b) gdb -pid=id(进程号)
         2)bt查看栈帧
         3)查看进程栈帧局部变量的值
                           info threads
         4)切换进程       thread Id(进程号)
         5)查看栈空间     bt full
         6)退出进程调试   detach
         7)退出gdb        q
        @一般说的线程锁是指默认锁,仅仅能加锁一次。回环锁为特殊的线程锁。
         能够多次加锁,一般用不到。
        @自旋锁的属性
         自旋锁:假设自旋锁已经被别的运行单元保持,调用者就一直循环查看是否该
         自旋锁的保持已经释放了锁,“自旋”就是循环查看的意思。
        @回环锁能够多次加锁,每加一次计数器加一。减锁使用时。每减一次计数器减一
        @1)尽量避免多锁穿插使用
         2)降低锁的分支
         3)线程锁必须在全部函数使用之前声明。相当于全局变量
         4)全局变量实现相互排斥,不能代替锁。全局变量不是原子的尽量不要用全局变量
            替代锁
        @尽可能缩短临界区的长度,避免第二次加锁导致程序被挂起(死锁)
         而不能异步相互排斥串行
        @加锁的目的就是实现异步相互排斥串行
        @不用锁的方法:将资源扩展,使相互排斥的对象变多。

    如:10个线程相应10个资源。


    信号量、消息队列和共享内存的差别:
        @信号量、消息队列是调用系统调用完毕,
        @共享内存仅仅是在申请时调用系统调用。之后都在自己的进程区间内
         通过指针进行操作。效率比較高。



  • 相关阅读:
    android开发之gridlayout使用入门
    android开发之merge结合include优化布局
    android开发布局优化之ViewStub
    FindBug:Call to static DateFormat
    SimpleDateFormat的使用问题
    某P2P开发商ERP系统核心业务介绍
    某P2P开发商ERP系统核心业务介绍
    xtu字符串 C. Marlon's String
    学渣乱搞系列之扩展KMP的那点事
    xtu字符串 D. 病毒侵袭
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6730534.html
Copyright © 2011-2022 走看看