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

来源:互联网 发布:淘宝试用报告在哪写 编辑:程序博客网 时间:2024/05/17 05:55

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
原创粉丝点击