您的位置:首页 > 运维架构 > Linux

linux 系统编程-学习笔记8--信号/线程

2014-10-13 21:02 711 查看
一、当系统接收到一个信号的时候,有三种处理方式:

1.系统默认

2.忽略

3.捕捉信号

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

: 通过handler标志去处理接受到的signum信号

signum:信号编号

1) SIGHUP 2 ) SIGINT3) SIGQUIT4) SIGILL5) SIGTRAP

6) SIGABRT 7) SIGBUS8) SIGFPE9) SIGKILL10) SIGUSR1

11) SIGSEGV 12) SIGUSR213) SIGPIPE14) SIGALRM15) SIGTERM

16) SIGSTKFLT 17) SIGCHLD18) SIGCONT19) SIGSTOP20) SIGTSTP

21) SIGTTIN 22) SIGTTOU23) SIGURG24) SIGXCPU25) SIGXFSZ

26) SIGVTALRM 27) SIGPROF28) SIGWINCH29) SIGIO30) SIGPWR

31) SIGSYS 34) SIGRTMIN35) SIGRTMIN+136) SIGRTMIN+237) SIGRTMIN+3

38) SIGRTMIN+4 39) SIGRTMIN+540) SIGRTMIN+641) SIGRTMIN+742) SIGRTMIN+8

43) SIGRTMIN+9 44) SIGRTMIN+1045) SIGRTMIN+1146) SIGRTMIN+1247) SIGRTMIN+13

48) SIGRTMIN+14 49) SIGRTMIN+1550) SIGRTMAX-1451) SIGRTMAX-1352) SIGRTMAX-12

53) SIGRTMAX-11 54) SIGRTMAX-1055) SIGRTMAX-956) SIGRTMAX-857) SIGRTMAX-7

58) SIGRTMAX-6 59) SIGRTMAX-560) SIGRTMAX-461) SIGRTMAX-362) SIGRTMAX-2

63) SIGRTMAX-1 64) SIGRTMAX

handler : 处理方式(函数指针)

1.系统默认 SIG_DFL

2.忽略 SIG_IGN

3.捕捉信号 信号处理函数

handler类型:

void (*sighandler_t)(int);

:sighandler_t 函数指针变量,类型:void (*)(int);

typedef void (*sighandler_t)(int);

:sighandler_t 函数指针类型:类型:void (*)(int);

sighandler_t handler;

:handler 函数指针变量 类型:void (*)(int);

构造信号处理函数:

void sig_int(int sig)

{

}

signal(SIGINT,sig_int);

{

handler = sig_int;

}

9) SIGKILL

19) SIGSTOP

注意:以上两个信号既不能被忽略也不能被捕捉

功能基本和signal一致,功能必signal强大,更加灵活

int sigaction(int signum, const struct sigaction *act,

struct sigaction *oldact);

signum :信号的编号

struct sigaction {

void (*sa_handler)(int);//用于接受信号的处理方式(信号处理函数地址)

void (*sa_sigaction)(int,siginfo_t*,void*);//用于接受信号的处理方式(信号处理函数地址),

//可以访问到siginfo_t 结构体,但是sa_flags

//需要跟上SA_SIGINFO标识

sigset_t
sa_mask; //信号集

int sa_flags;//标志 eg:SA_SIGINFO

void (*sa_restorer)(void);

};

进程:

1.每个进程都有自己的资源空间 ==>浪费空间

进程间切换需要数据拷贝,时间

2.不同的进程间要进行资源共享:需要用到进程间

通信【管道,。。。。消息队列,共享内存,socket】

浪费CPU资源(空间和时间)

系统的开销比较大:

解决方案:

vfork=>父子进程共享资源空间 ==>节省空间==>但是该函数由缺陷

==>所以才有了线程.

再一个进程中开辟多个线程

1.该进程成为主线程:对次线程进行任务分配

2.该进程下的所有的线程共享该进程的资源空间

3.那个线程先执行,是有内核确定的

======================================================

内核遵循任务调度规则

线程间切换条件:

1.时间片结束

2.线程执行结束

3.线程被阻塞

4.线程被中断

5.被优先级高的线程抢占

6.被其他线程取消

..................

注意:保护现场(目的是能切换回来)

=========================================================

进程的操作:

1.进程的创建

2.进程的执行

3.进程的退出

进程的几种状态:

1.等待/就绪态

2.运行态

3.终止态

4.僵尸态

========================================================

线程的操作:

1.线程的创建

2.线程的执行

3.线程的退出

4.线程的取消

线程的几种状态:

1.等待/就绪态 ==>吃饭/睡觉

2.运行态 ==>工作

3.终止态 ==>累死了

=======================================================

________________________________________________________

sudo apt-get install manpages-posix-dev

________________________________________________________



1.线程的创建


#include <pthread.h>

int pthread_create(pthread_t *restrict thread,

const pthread_attr_t *restrict attr,

void *(*start_routine)(void*), void *restrict arg);

功能: 创建一个新的线程

restrict thread : 用于存放新建线程的线程ID

restrict attr : 线程控制

void *(*start_routine)(void*) : 函数指针用于接受线程执行函数的地址[新线程从这里开始执行]

restrict arg); : 传给线程执行函数的参数

返回值:

线程创建成功返回0

否则返回相应的错误码

2.线程的执行函数

void *do_work(void *arg)

{

}

pthread_t pthread_self(void);

获取本线程的线程ID

================================================================================================

线程的退出:

次线程的退出方式:

1.return 返回给主线程

2.exit 直接退出本进程

3.pthread_exit 返回给主线程

pthread_exit返回给主线程之后,并不意味这资源被回收,它分为以下两种情况:

1.可分离态 : 线程的资源空间被分离出来的,pthread_exit之后,由系统统一回收资源

2.可结合态 : 需要主线程调用函数pthread_join等待次线程回收资源

主线程的退出方式:

1.return/exit 返回给系统

2.pthread_exit

调用pthread_exit退出,本进程成为僵尸进程,会一直等待次线程执行完毕

===============================================================================================

可结合态和可分离态:

1.可结合态:在线程建立的时候一般默认为可结合态,需要主线程调用函数pthread_join等待回收次线程的资源

int pthread_join(pthread_t thread, void **value_ptr);

功能:pthread_join等待回收次线程的资源

pthread : 要等待的次线程的线程ID

value_ptr : 用于存放次线程调用return 返回的状态

成功:返回 0

2.可分离态 : 线程的资源空间被分离出来的,pthread_exit()之后,

1)由系统统一回收资源

2)调用pthread_join 会失败

int pthread_detach(pthread_t thread);

功能:把线程pthread设置为分离态

thread : 要设置在的线程的ID

调用成功:返回 0 否则返回对应的错误码。

4.线程的取消

int pthread_cancel(pthread_t thread);

取消线程thread

1.发送信号给线程thread 告诉它,它要被取消了,先收拾好东西

2.当线程thread准备好之后,结束线程thread

线程结束之后也会调用线程清理函数

void pthread_cleanup_push(void (*routine)(void*), void *arg);

功能:入栈,对清理函数进行入栈登记

void (*routine)(void*) : 函数指针,用于接受线程清理函数的地址

_______________________________________________

//线程清理函数

void clean_up(void *)

{

}

_______________________________________________

void *arg : 传给线程清理函数的参数,可以为NULL

void pthread_cleanup_pop(int execute);

功能:线程清理函数出栈(销毁清理函数)

execute : 1 / 0

调用pop的情况:

1.pthread_cleanup_pop(1);

2.pthread_exit()

pthread_cleanup_pop(0);

3.pthread_cancel==>被其他线程取消

pthread_cleanup_pop(0)

================================================

如果多个线程对同一个文件进行操作,需要解决同步问题

:当一个线程在对文件进行操作的时候,为了不受到其他线程的影响,

 在该线程进行操作文件的时候上一把锁,之后其他线程就无法对该文件再进行操作

当该线程操作完成,并解锁之后,其他线程才能获取到该锁,才能对文件进行操作

互斥锁:

int pthread_mutex_init(pthread_mutex_t *restrict mutex,

const pthread_mutexattr_t *restrict attr);

功能:初始化互斥锁【变量】

int pthread_mutex_lock(pthread_mutex_t *mutex);

功能:上锁(强制性锁:不管前有没有被上锁,直接在次上锁)

int pthread_mutex_trylock(pthread_mutex_t *mutex);

功能:上锁(建议性锁:在上锁之前,先判断前有没有被上锁,如果已经被上锁,则不上锁

   如果没有上锁,直接在次上锁

int pthread_mutex_unlock(pthread_mutex_t *mutex);

功能:解锁

int pthread_mutex_destroy(pthread_mutex_t *mutex);

功能:销毁互斥锁(释放内存)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: