Linux线程浅析[线程的同步和互斥之线程死锁,线程与信号的关系]

Linux线程浅析[线程的同步和互斥之线程死锁,线程与信号的关系]

  1. 线程死锁
  2. 线程与信号

记得以前在学习java线程的时候,也会接触死锁,当时不断强调锁千万不要不能去做嵌套,不然容易一个线程在执行的时候所需要的锁被别的线程持有了,而别的线程执行的时候,它的锁又被第一个线程持有,这种相互持有锁却释放不了的这样的一种情况

线程死锁

什么是死锁?

两个线程试图同时占用两个资源,并按不同的次序锁定相应的共享资源

解决方式

1:按相同的次序锁定相应的共享资源
2:pthread_mutex_trylock(),它是函数pthread_mutex_lock()的非阻塞函数

打造属于自己的死锁:

/*
 * ===========================================================================
 *
 *       Filename:  pthread_dead_lock.c
 *    Description:  
 *        Version:  1.0
 *        Created:  2017年04月04日 21时30分44秒
 *       Revision:  none
 *       Compiler:  gcc
 *         Author:   (), 
 *        Company:  
 *
 * ===========================================================================
 */

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>

typedef struct{
  int res;
  pthread_mutex_t mutex_one;
}ArgvType1;

typedef struct{
  int res;
  pthread_mutex_t mutex_two;
}ArgvType2;

typedef struct{
  ArgvType1* type1;
  ArgvType2* type2;
}Argv;


void* one_th(void* argv){
  Argv* argv_pointer = (Argv*)argv;
  pthread_mutex_lock(&argv_pointer->type1->mutex_one);
  printf("0x%lx wait type2",pthread_self());
  sleep(1);
  pthread_mutex_lock(&argv_pointer->type2->mutex_two);
  pthread_mutex_unlock(&argv_pointer->type1->mutex_one);
  pthread_mutex_unlock(&argv_pointer->type2->mutex_two);
  return (void*)0;
}
void* two_th(void* argv){
  Argv* argv_pointer = (Argv*)argv;
  pthread_mutex_lock(&argv_pointer->type2->mutex_two);
  printf("0x%lx wait type2",pthread_self());
  sleep(1);
  pthread_mutex_lock(&argv_pointer->type1->mutex_one);
  pthread_mutex_unlock(&argv_pointer->type2->mutex_two);
  pthread_mutex_unlock(&argv_pointer->type1->mutex_one);
  return (void*)0;
}


int main(int argc,char* argv1[]){
   pthread_t thread_one,thread_two;
   int err;
   ArgvType1 argvtype1;
   ArgvType2 argvtype2;
   argvtype1.res = 0;
   argvtype2.res = 0;
   pthread_mutex_init(&argvtype1.mutex_one,NULL);
   pthread_mutex_init(&argvtype2.mutex_two,NULL);

   Argv argv={&argvtype1,&argvtype2};
  if((err = pthread_create(&thread_one,NULL,one_th,(void*)&argv))!=0){
     printf("thread_one create error");
  }

  if((err = pthread_create(&thread_two,NULL,two_th,(void*)&argv))!=0){
     printf("thread_two create error");
  }

  pthread_join(thread_one,NULL);
  pthread_join(thread_two,NULL);
  pthread_mutex_destroy(&argv.type1->mutex_one);
  pthread_mutex_destroy(&argv.type2->mutex_two);


  return 0;
}

上面采用的是两把锁进行相互嵌套的形式,这样形式务必会造成死锁.解决方案已经在上面给出了

线程与信号

在前一篇幅Linux线程浅析[线程的同步和互斥之线程信号量]中我们提到了信号量,而这个信号量其实就是信号的量集,即信号的增减运算.而并非是具体的信号类型.在这里提到的信号,则被视为具体的信号类型.类似于进程中 kill -l 后显示出来的具体信号类型.

在进程中的主线程中我们有信号的捕获和屏蔽,但是在进程对应的子线程中,我们能否对其信号进行捕获或者屏蔽呢??

线程中的信号特点:

 1:进程中的每个线程都有自己的信号屏蔽字和信号未决字
 2:信号的处理方式是进程中所有线程共享的
 3:进程中的信号是传递到单个线程的
 4:定时器是进程的资源,进程中所有的线程共享相同的定时器
     子线程中调用alarm函数产生的alarm信号会发送给主线程

线程信号中的相关函数(sleep和parse都是可以由信号中断其状态的)

 #include<signal.h>
 int pthread_sigmask(int how,const sigset_t *restrict set,sigset_t *restrict oset);
 功能:线程的信号屏蔽
 返回:成功返回0,失败返回错误编号

如何屏蔽信号:调用方式如下

 sigset_t set;
 sigemptyset(&set);
 sigaddset(&set,SIGALRM);
 pthread_sigmask(SIG_SETMASK,&set,NULL);

由于时间上的原因,线程信号屏蔽就不在这里进行演示了,有空在补全吧.(线程在处理相关共享信号的时候,需要格外注意其使用)

欢迎持续访问博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值