美文网首页
多线程锁

多线程锁

作者: 7ee64cf5edb2 | 来源:发表于2019-10-22 19:20 被阅读0次
1. 背景知识:
多线程中经常需要使用到锁(pthread_mutex_t)来完成多个线程之间的某些同步操作
• 互斥锁:为了使不同线程互斥的使用某个资源
    ○ 锁的创建:pthread_mutex_init
        § pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
        § int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t * attr);
    ○ 锁的属性:
        pthread_mutexattr_init(pthread_mutexattr_t *mattr)
        pthread_mutexattr_settype(pthread_mutexattr_t *attr , int type)
        pthread_mutexattr_gettype(pthread_mutexattr_t *attr , int *type)
        § 普通锁:PTHREAD_MUTEX_TIMED_NP(当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性)
        § 嵌套锁:PTHREAD_MUTEX_RECURSIVE_NP(允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争)
        § 检错锁:PTHREAD_MUTEX_ERRORCHECK_NP(如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁)
        § 适应锁:PTHREAD_MUTEX_ADAPTIVE_NP(动作最简单的锁类型,仅等待解锁后重新竞争)
    ○ 锁的释放:pthread_mutex_destory
    ○ 锁操作:
        § 加锁:int pthread_mutex_lock(pthread_mutex_t *mutex)
        § 解锁:int pthread_mutex_unlock(pthread_mutex_t *mutex)
        § 测试加锁:int pthread_mutex_trylock(pthread_mutex_t *mutex)
• 条件锁:为了保证不同线程之间有顺序(通过条件控制)地完成某个流程
    ○ 等待方式:
        § 无条件等待:pthread_cond_wait()
        § 计时等待:pthread_cond_timedwait()
    ○ 激活条件:
        §  int pthread_cond_signal(pthread_cond_t *cond); 激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个
        § int pthread_cond_broadcast(pthread_cond_t *cond);  激活所有等待线程

互斥锁:

#include <pthread.h>
#include <stdio.h>
 
pthread_mutex_t mutex ;
void *print_msg(void *arg){
        int i=0;
        pthread_mutex_lock(&mutex);
        for(i=0;i<15;i++){
                printf("output : %d\n",i);
                usleep(100);
        }
        pthread_mutex_unlock(&mutex);
}
int main(int argc,char** argv){
        pthread_t id1;
        pthread_t id2;
        pthread_mutex_init(&mutex,NULL);
        pthread_create(&id1,NULL,print_msg,NULL);
        pthread_create(&id2,NULL,print_msg,NULL);
        pthread_join(id1,NULL);
        pthread_join(id2,NULL);
        pthread_mutex_destroy(&mutex);
        return 1;
}

条件锁:

//一个生产者消费者模型
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>

typedef struct node
{
    int num;
    struct node *next;
} node_t;

typedef node_t *list_t;
list_t head = NULL;
pthread_mutex_t mutex =
    PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond =
    PTHREAD_COND_INITIALIZER;

//消费者线程
void *consume(void *arg)
{
    node_t *tmp;
    while (1)
    {
        //加锁
        pthread_mutex_lock(&mutex); //对临界变量加锁
        if (head == NULL)           //如果头部指向空,等待
            pthread_cond_wait(&cond, &mutex);
        tmp = head;        //将要删除的节点赋值给中间值,然后头指针指向下一个
        head = head->next; //
        //解锁
        pthread_mutex_unlock(&mutex);
        //消费tmp节点
        printf("consum:%d\n", tmp->num);
        free(tmp);
        tmp = NULL;
        sleep(rand() % 5);
    }
}

//生产者线程
void *product(void *arg)
{ //函数的格式void *(*start_routine) (void *),返回值是指针,参数也是
    node_t *n;
    while (1)
    {
        //生产一个新的节点
        n = (node_t *)malloc(sizeof(node_t));
        n->num = rand() % 1000 + 1;
        printf("p:%d\n", n->num);
        //加锁
        pthread_mutex_lock(&mutex);
        //将新节点放入到链表的头部
        n->next = head;
        head = n;
        //解锁
        pthread_mutex_unlock(&mutex);
        //通知消费者
        pthread_cond_signal(&cond);
        sleep(rand() % 5);
    }
}
int main(void)
{
    pthread_t pid, cid;
    //设置随机数的种子
    srand(time(NULL));
    //创建两个线程,用于生产者和消费者
    pthread_create(&pid, NULL, product, NULL); //创建线程后即执行该线程
    pthread_create(&cid, NULL, consume, NULL); //参数含义是(存放ID的缓存区,NULL缺省属性,线程的执行函数,函数的唯一参数)
    //等待线程的汇合
    pthread_join(pid, NULL);
    pthread_join(cid, NULL);
    //销毁mutex锁
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    return 0;
}

相关文章

  • 起底多线程同步锁(iOS)

    起底多线程同步锁(iOS) 起底多线程同步锁(iOS)

  • 浅析乐观锁、悲观锁与CAS

    乐观锁与悲观锁 处理多线程并发访问最常用的就是加锁,锁又分成乐观锁和悲观锁。 悲观锁 在多线程访问共享资源时,同时...

  • 多线程与锁

    多线程与锁

  • 多线程 (三)iOS中的锁

    ios 多线程--锁

  • 多线程(四)

    上篇多线程(三)我们看了多线程的安全隐患 以及各种锁的简单使用,接下来我们来看看锁的比较、以及自旋锁、互斥锁比较 ...

  • 解决线程同步的方案汇总总结

    这是一篇继上一篇继续介绍多线程同步的博客.(你了解多线程自旋锁、互斥锁、递归锁等锁吗?[https://www.j...

  • OC--各种线程锁

    参考:正确使用多线程同步锁@synchronized()iOS中的锁iOS多线程安全详解iOS 常见知识点(三):...

  • zookeeperDistributedLock

    分布式锁: 分布式锁是什么? 通常说的锁是单进程多线程的锁,在多线程并发编程中用于线程之间的数据共享 分布式锁 指...

  • 锁与多线程同步的实现

    Java当中的锁都是为了保证多线程同步执行。如果没有锁的话,多线程是异步执行的。 什么是多线程同步? 请看下面的代...

  • iOS线程同步

    线程同步 提到多线程大家肯定会提到锁,其实真正应该说的是多线程同步,锁只是多线程同步的一部分。 多线程对于数据处理...

网友评论

      本文标题:多线程锁

      本文链接:https://www.haomeiwen.com/subject/arrcvctx.html