l2tp连接尝试失败 因为安全层在初始化_线程安全互斥锁

e386fe917e68ad1e05b3f572f905ad3e.gif

1认知

线程安全机制:

由于线程它是共享进程里面所有的资源,当然这里面就会包括虚拟内存里面所有的东西(包含全局变量,堆内存,映射的内存及程序段落等),它也继承了进程当中所有的资源(文件描述符,信号资源等),便会出现一种情况:同一个资源有可能会出现多个线程访问及更改。这是一件比较尴尬的事情,我们可以假设,如果你有一个余额,你可以去花费这笔余额,你的女朋友也可以支付宝或者是微信来花费你这笔余额,这个时候如果稍有不慎,大家就会产生逻辑冲突。所以提出了我们线程的同步互斥机制,来解决这个安全漏洞。

7ed9651d41914b16e3c7e5d97d89e1b4.png

互斥锁:

由posix给我们提供的一个线程的配合的“锁”资源,达到一种逻辑:当我们需要去操作共享资源的时候,我们自己主动去跟系统拿这个互斥锁(上锁操作),这个时候如果别人也想要过来拿这把锁的时候,便陷入睡眠,一直等到先拿了这把互斥锁的人还给系统(解锁操作)后,下一个人才会被唤醒,然后拿走这把锁,以保证我们操作这个公有资源的时候,有且只有一个人在同一时间段里可以访问,其他人如果访问则陷入睡眠。

互斥锁使用非常简便,但他也有不适用的场合——假如要保护的共享资源在绝大多数的情况下是读操作,就会导致这些本可以一起读的线程阻塞在互斥锁上,资源得不到最大的利用,但可以用读写锁解决这个问题。下篇笔记--读写锁。

2相关API

互斥锁的初始化函数:                   

#includeintpthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t*restrict attr);

参数:

       Mutex:需要初始化的互斥锁

       Attr:这个参数设置为NULL,代表按照默认的互斥锁进行初始化

返回值:

       成功则返回0,失败返回一个错误值,errno不会被设置

 互斥锁的销毁函数:                 

    #include              intpthread_mutex_destroy(pthread_mutex_t *mutex);

参数:

     Mutex:销毁的线程锁

返回值:

      成功则返回0,失败返回一个错误值,errno不会被设置

互斥锁的操作函数:                 

#includeintpthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t*mutex);intpthread_mutex_unlock(pthread_mutex_t*mutex);

函数功能:

       pthread_mutex_lock:获取指定的互斥锁(加锁操作),如果这个互斥锁已经被别人使用了(被别人加锁操作了),则你的线程会在这里陷入睡眠

        pthread_mutex_trylock:尝试去获取指定的互斥锁,如果这个互斥锁已经被别人使用了,他不会在这里睡眠,直接返回错误

       pthread_mutex_unlock:解除互斥锁的占用(解锁操作),如果这个时候有人因为获取这把锁而陷入睡眠,则会将最先去获取这把锁的人唤醒,让其继续操作这把锁

参数:

        mutex:需要操作的互斥锁

  返回值:

         成功则返回0,失败则返回一个错误值,errno不会被设置

7ed9651d41914b16e3c7e5d97d89e1b4.png

总结:

1,什么时候我们需要用到互斥锁:一旦操作一个共有资源,我们都应该加锁,以确保逻辑没有漏洞。

2,为了防止死锁(线程在执行的过程中,获取了互斥锁,而刚好被取消掉,你的锁来不及解开就会造成死锁),我们会在获取锁之后的操作中,加上pthread_cleanup_push跟pthread_cleanup_pop函数,包裹进线程的锁操作中

3代码展示

对互斥锁的操作无非就是:初始化、加锁、解锁、销毁。下面的代码如何使用互斥锁来互斥地访问标准输出,来理解互斥锁的正确使用:

#include #include #include #include #include #include int count = 10;void *thread(void *arg){    pthread_mutex_t *mutex = arg;      while(1)    {        pthread_mutex_lock(mutex);//加锁操作=把锁拿过来            printf("tid=%ld, in thread count=%d\n", pthread_self(), count);            if(count == 0)        {              pthread_mutex_unlock(mutex);//解锁操作=把锁还回去              break;          }        sleep(1);//代表你女朋友花钱      count -= 1;        pthread_mutex_unlock(mutex);//解锁操作=把锁还回去    }        return   NULL;}void *init_mutex(void *arg){    pthread_mutex_t *mutex = arg;      pthread_mutex_init( mutex, NULL);//制造一把互斥锁      return NULL;}int main(void){    int retval;    pthread_t tid[3];      pthread_mutex_t mutex;        pthread_create(tid, NULL, init_mutex, &mutex);        pthread_join(tid[0], NULL);          pthread_create(tid, NULL, thread, &mutex);    pthread_create(tid+1, NULL, thread, &mutex);    pthread_create(tid+2, NULL, thread, &mutex);      pthread_join(tid[0], NULL);    pthread_join(tid[1], NULL);    pthread_join(tid[2], NULL);        pthread_mutex_destroy(&mutex);//销毁这把互斥锁      return 0;}

0eb0e81e616c57995ce4c182baecb5ad.png

记录 点点滴滴的笔记 欢迎关注,共同学习

小浩笔记

66898afcfe5aa7b57a239df6b0187d4d.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值