zoukankan      html  css  js  c++  java
  • linux线程操作

    初始化条件变量

    int pthread_cond_init(pthread_cond_t *cv,pthread_cond_attr *cattr);
    函数返回值:返回0表示成功,返回其他表示失败。
    参数:        pthread_cond_attr是用来设置pthread_cond_t的属性,当传入的值是NULL的时候表示使用默认的属性。

    函数返回时,创建的条件变量保存在cv所指向的内存中,可以用宏PTHREAD_COND_INITIALIZER来初始化条件变量。值得注意的是不能使用多个线程初始化同一个条件变量,当一个线程要使用条件变量的时候确保它是未被使用的。

    条件变量的销毁

    int pthread_cond_destroy(pthread_cond_t *cv);
    返回值:返回0表示成功,返回其他值表示失败。

    条件变量的使用:

    int pthread_cond_wait(pthread_cond_t *cv,pthread_mutex_t *mutex)
    int pthread_cond_signal(pthread_cond_t *cv);

    使用方式如下:

    pthread_mutex_lock(&mutex)
    while or if(线程执行的条件是否成立)
        pthread_cond_wait(&cond,&mutex);
    线程执行
    pthread_mutex_unlock(&mutex);

    为什么要加锁

    1. 线程在执行的部分访问的是进程的资源,有可能多个线程需要访问它,为了避免由于线程并发执行所引起的资源竞争,所以要让每个线程互斥的访问公共资源。
    2. 如果while或if判断不满足线程的执行条件时,线程回调用pthread_cond_wait阻塞自己。pthread_cond_wait被调用线程阻塞的时候,pthread_cond_wait会自动释放互斥锁。线程从调用pthread_cond_wait到操作系统把他放在线程等待队列之后的时候释放互斥锁。

    使用while和if判断线程执行条件释放成立的区别。

    在多线程资源竞争的时候,在一个使用资源的线程里面(消费者)判断资源是否可用,不可用便调用pthread_cond_wait,在另一个线程里面(生产者)如果判断资源可用的话,则会调用pthead_cond_signal发送一个资源可用的信号。

    但是在wait成功之后,资源就不一定可以被使用,因为同时有两个或两个以上的线程正在等待次资源,wait返回后,资源可能已经被使用了,在这种情况下

    while(resource == FALSE)
        pthread_cond_wait(&cond,&mutex);

    如果之后只有一个消费者,就可使用if。

    分解pthread_cond_wait动作为以下步骤:

    1. 线程放在等待队列上,解锁
    2. 等待pthread_cond_signal或者pthread_cond_broadcast信号之后去竞争锁
    3. 若竞争到互斥锁则加锁

    有可能多个线程在等待这个资源可用的信号,信号发出去之后只有一个资源可用,但是有A,B两个线程在等待,B速度比较快,获得互斥锁,然后加锁,消耗资源,然后解锁,之后A获得互斥锁,但它回去发现资源已经被使用了,它便有两个选择,一个失去访问不存在的资源,另一个就是继续等待,那么等待下去的条件就是使用while,要不然使用if的话pthread_cond_wait返回后,就会顺序执行下去。

    等待线程:

    pthread_cond_wait      前要加锁

    pthread_cond_wait      内部会解锁,然后等待条件变量被其他线程激活

    pthread_cond_wait      被激活后会再自动加锁

    激活线程

    加锁(和等待线程用同一个锁)

    pthread_cond_signal   发送信号(阶跃信号前最后判断有无等待线程)

    解锁

    激活线程的上面三个操作再运行时间上都是再等待线程的pthread_cond_wait函数内部。

    /***
    pthread_if.c
    ***/
    #include<stdio.h>
    #include<sys/types.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<pthread.h>
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    
    int count = 0;
    
    void *decrement(void *arg)
    {
        printf("in derment
    ");
        pthread_mutex_lock(&mutex);
        if(count == 0)
            pthread_cond_wait(&cond,&mutex);
        count--;
        printf("----decrement:%d
    ",count);
        printf("out decrement
    ");
        pthread_mutex_unlock(&mutex);
        return NULL;
    }
    
    void *increment(void *arg)
    {
        printf("in increment
    ");
        pthread_mutex_lock(&mutex);
        count++;
        printf("-----increment:%d
    ",count);
        if(count != 0)
        {
            pthread_cond_signal(&cond);
        }
        printf("out increment
    ");
        pthread_mutex_unlock(&mutex);
        return NULL;
    }
    
    int main()
    {
        pthread_t tid_in,tid_de;
        pthread_create(&tid_de,NULL,(void*)decrement,NULL);
        sleep(1);
        pthread_create(&tid_in,NULL,(void*)increment,NULL);
        sleep(1);
    
        pthread_join(tid_de,NULL);
        pthread_join(tid_in,NULL);
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
        return 0;
    }
    /***
    pthread_while.c
    ***/
    #include<stdio.h>
    #include<stdlib.h>
    #include<pthread.h>
    #include<unistd.h>
    
    typedef struct node_s
    {
        int data;
        struct node_s *next;
    }node_t;
    
    node_t *head = NULL;
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    
    void cleanup_handler(void *arg)
    {
        printf("cleanup_handler is running.
    ");
        free(arg);
        pthread_mutex_unlock(&mutex);
    }
    
    void *thread_func(void *arg)
    {
        node_t *p = NULL;
        pthread_cleanup_push(cleanup_handler,p);
        while(1)
        {
            pthread_mutex_lock(&mutex);
            while(NULL == head)
                pthread_cond_wait(&cond,&mutex);
            p = head;
            head = head->next;
            printf("process %d node
    ",p->data);
            free(p);
            pthread_mutex_unlock(&mutex);
        }
        pthread_cleanup_pop(0);
        return NULL;
    }
    
    int main()
    {
        pthread_t tid;
        node_t *temp = NULL;
        int i;
        pthread_create(&tid,NULL,(void*)thread_func,NULL);
    
        for(i = 0; i < 10; i++)
        {
            temp = (node_t*)malloc(sizeof(node_t));
            temp->data = i;
            pthread_mutex_lock(&mutex);
            temp->next = head;
            head = temp;
            pthread_cond_signal(&cond);
            pthread_mutex_unlock(&mutex);
            sleep(1);
        }
        pthread_cancel(tid);
        pthread_join(tid,NULL);
        return 0;
    
    }
  • 相关阅读:
    MyBatis进阶(一)
    git命令整理
    今天的任务--git练习
    深入浅出JavaScript(一)
    数据结构_树_二叉搜索树
    网络_体系结构
    数据结构_树
    算法_五大经典搜索算法
    SpringMVC入门
    spring 线程异步执行
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11613064.html
Copyright © 2011-2022 走看看