目录
1.linux线程
1.1 基本介绍
1.2 线程信息
1.3 线程创建
1.4 线程终止
1.5 线程指定数据
1.5 线程同步
2.linux 信号与信号处理
2.1 信号介绍
2.2 信号种类
2.3 信号处理
2.4 信号发送
2.5 信号屏蔽
1.linux线程
1.1 基本介绍
线程是计算机独立运行的最小单位,也可以看出线程是系统分配CPU资源的基本单位,每个线程在系统给它时间片内,取得CPU的控制权,执行线程中的代码。
相对于进程来说,线程创建消耗资源少,线程切换速度快,进程内的线程数据共享,通信效率高。
1.2 线程信息
线程ID,每个线程有唯一的线程ID
寄存器,如PC计数器,堆栈指针等
堆栈
信号掩码
优先级
线程私有空间等。
1.3 线程创建
#include
typedef struct
{
int detachstate;
int schedpolicy;
struct sched_param schedparam;
int inheritsched;
int scope;
size_t guardsize;
int stackaddr_set;
void* stackaddr;
size_t stacksize;
}pthread_attr_t;
int pthread_create(pthread_t *thread,pthread_attr_t* attr,void* (*start_routine)(void*),void *arg);
pthread_t pthread_self(void);
int pthread_equal(pthread_t thread1,pthread_t thread2);
int pthread_once(pthread_once_t* once_control,void (*int_routine)(void));
#include
#include
#include
#include
int* thread_routine(void* arg);
int main(void)
{
pthread_t thid;
printf("main thread id is %u rn",pthread_self());
if (pthread_create(&thid,NULL,(void*)thread_routine,NULL) != 0)
{
printf("thread create failed! rn");
exit(1);
}
sleep(1);
exit(0);
}
int* thread_routine(void* arg);
{
pthread_t thid;
thid = pthread_self();
printf("routine thread id is %u rn",thid);
return NULL;
}
1.4 线程终止
1> 从线程函数中,通过return返回终止;
2> 调用pthread_exit() 终止线程。
线程终止时的资源释放,如下成对出现的红函数,可以跟着线程的终止而释放资源
#include#define pthread_cleanup_push(routine,arg) { struct _pthread_cleanup_buffer buffer; _pthread_cleanup_push(&buffer,(routine),(arg)); #define pthread_cleanup_pop _pthread_cleanup_pop(&buffer,(routine));}
线程间的同步等待
#includevoid pthread_exit(void* ret); int pthread_join(pthread_t th,void* thread_ret); int pthread_detach(pthread_t th);
1.5 线程指定数据
线程指定数据(thread specific data TSD),通过键值访问方式,来达到线程私有数据目的。
具体方法是,各个线程,使用公有的键来访问线程数据,而每个线程中使用该键对应的数据是不一致的,以此,达到私有数据访问的目的。
#includeint pthread_key_create(pthread_key_t *key,void (*destr_function)(void*)); int pthread_setspecific(pthread_key_t key,const void * ptr); void* pthread_getspecific(pthread_key_t key); int pthread_key_delete(pthread_key_t key);
1.5 线程同步
同步的方式,主要包含,互斥锁,条件变量,异步信号。
互斥锁
#includepthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *mutexattr); 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);
条件变量
#includepthread_cond_t cond = PTHREAD_COND_INITIALIZER; int pthread_cond_init(pthread_cond_t 8cond,pthread_condattr_t *cond_attr); int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex); int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const struct timespec *abstime); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); int pthread_cond_destroy(pthread_cond_t *cond);
异步信号
#includeint pthread_kill(pthread_t threadid,int signo); int pthread_sigmask(int how,const sigset_t *newmask,sigset_t *oldmask); int sigwait(const sigset_t *set,int *sig);
2.linux 信号与信号处理
2.1 信号介绍
信号是一种软中断,一种处理异步事件的方式,主要用来通知进程发生了事件,以及传递数据。
信号的来源:终端按键,硬件异常,kill、sigqueue发送信号,alarm/timer等发送信号等;
2.2 信号种类
| 信号 | 说明 |
| SIGHUP | 用户退出shell,该shell启动的进程收到该信号,默认为退出进程 |
| SIGINT | 用于按下 CTRL+C 发出该终端启动的程序该信号,默认为终止进程 |
| SIGQUIT | 用于按下 CTRL+ 向正在运行的程序发出该信号,默认终止进程,产生core文件 |
| SIGILL | CPU 检测非法指令,终止进程,产生core文件 |
| SIGTRAP | 断点指令或trap指令产生,终止进程,产生core文件 |
| SIGABRT | 调用abort函数产生该信号,终止进程,产生core文件 |
| SIGBUS | 非法访问地址,内存地址对齐出错,终止进程,产生core文件 |
| SIGFPE | 致命的算术错误,如浮点运算错误,溢出,除0等,终止进程,产生core文件 |
| SIGKILL | 无条件终止进程,不可被忽略 处理和阻塞 |
| SIGUSR1 | 用户定义信号 |
| SIGSEGV | 进程进行了无效的内存访问,终止进程,产生core文件 |
| SIGUSR2 | 用户定义信号 |
| SIGPIPE | broken pipe,向一个没有读端的管道写数据 |
| SIGALRM | 定时器超时,系统调用alarm设置 |
| SIGTERM | 程序terminate信号,可被阻塞和处理,执行kill是产生这个信号 |
| SIGCHLD | 子进程结束时,父进程收到该信号,默认忽略该信号 |
| SIGCONT | 让一个暂停的进程继续执行 |
| SIGSTOP | stop 进程的执行,只是让进程暂停,不可被忽略处理和阻塞 |
| SIGTSTP | 停止进程的运行,可被处理和忽略, 一般CTRL+Z发出,默认为暂停进程 |
| SIGTTIN | 后台进程从用户终端读数据,终端进程收到该信号,默认暂停进程 |
| SIGTTOU | 后台进程从用户终端写数据,终端进程收到该信号,默认暂停进程 |
| SIGURG | 套接字 socket有紧急数据时,向正在运行的进程发出该信号,默认动作为忽略 |
| SIGXCPU | 进程执行时间超过分配给该进程的CPU时间,默认为终止进程 |
| SIGXFSZ | 超过文件最大长度限制,终止进程,产生core文件 |
| SIGVTALRM | 虚拟时钟超时,默认动作终止进程 |
| SIGPROF | 同SIGVTALRM |
| SIGWINCH | 窗口大小改变发出,默认忽略该信号 |
| SIGIO | 异步IO事件,默认忽略 |
| SIGPWR | 关机,默认终止进程 |
| SIGSYS | 无效的系统调用,终止进程,产生core文件 |
| SIGRTMIN~SIGRTMAX | linux 实时信号,无固定意义 |
| 1~31 不可靠信号 | 33~64 可靠信号,不会丢失 |
| 优先级 | 实时信号,值越小,优先级越高 |
2.3 信号处理
#include
typedef void (*sighandler_t)(int);
struct sigaction
{
void (*sa_handler)(int);
void (*sa_sigaction)(int,siginfo_t*,void*);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
sighandler_t signal(int signum,sighandler_t handler);
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);
#include
#include
#include
int tmp = 0;
void sigint_handler(int signo);
int main(void)
{
struct sigaction act;
act.sa_handler = sigint_handler;
act.sa_flags = SA_NOMASK;
sigaction(SIGINT,&act,NULL);
while(1);
exit(0);
}
void sigint_handler(int signo)
{
printf("recv SIGINTn");
sleep(5);
tmp++;
printf("tmp value is %d n",tmp);
}
执行以上程序,按CTRL+C 出现效果,按CTRL+ 退出
#includeint pause(void);
2.4 信号发送
kill 函数发送
int kill(pid_t pid,int sig);
pid>0 发送给指定pid信号
pid=0,发送给进程组
pid=-1 广播给除init和自身的所有进程
pid < -1,进程组-pid的所有进程
raise函数发送
int raise(ing sig);
sigqueue函数发送
int sigqueue(pid_t pid,int sig,const union sigval var);
支持带参数的发送信号
alarm函数发送
unsigned int alarm(unsigned int seconds);
按设定的时间发送SIGALRM信号
abort函数发送
void abort(void);
发送SIGABRT信号
2.5 信号屏蔽
int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);
int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);
how,主要包含如下设置
SIG_BLOCK,设置为信号集并集 set| oldset
SIG_SETMASK,设置为set
int sigpending(sigset_t *set);
获取当点pending的信号集
int sigsuspend(const sigset_t *mask)
将信号屏蔽码设置为mask,和pause一样,等待信号的发生并执行信号处理函数。


![[linux专题]基于linux线程与信号处理 [linux专题]基于linux线程与信号处理](http://www.mshxw.com/aiimages/31/657587.png)
