[linux专题]基于linux线程与信号处理

 

目录

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;     /*
/*create_thread.c example*/

#include 
#include 
#include 
#include 

int* thread_routine(void* arg);

int main(void)
{
    pthread_t thid;

    printf("main thread id is %u \r\n",pthread_self());

    if (pthread_create(&thid,NULL,(void*)thread_routine,NULL) != 0)
    {
        printf("thread create failed! \r\n");
        exit(1);
    }
    sleep(1);
    exit(0);
}

int* thread_routine(void* arg);
{
    pthread_t thid;

    thid = pthread_self();
    printf("routine thread id is %u \r\n",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));}

线程间的同步等待

#include 

/*@desp,线程退出
*       
*/
void pthread_exit(void* ret);

/*@desp,挂起自己,等待一个线程结束,
*       一个线程仅仅允许一个线程等待终止
*/
int pthread_join(pthread_t th,void* thread_ret);

/*@desp,设置线程是否允许被同步
*       
*/
int pthread_detach(pthread_t th);

1.5 线程指定数据

线程指定数据(thread specific data TSD),通过键值访问方式,来达到线程私有数据目的。

具体方法是,各个线程,使用公有的键来访问线程数据,而每个线程中使用该键对应的数据是不一致的,以此,达到私有数据访问的目的。

#include 

/*@desp,为线程,创建键值,私有数据*/
int pthread_key_create(pthread_key_t *key,void (*destr_function)(void*));

/*@desp,设置键值对应的私有数据*/
int pthread_setspecific(pthread_key_t key,const void * ptr);

/*@desp,获取键值对应的私有数据*/
void* pthread_getspecific(pthread_key_t key);

/*@desp,删除键值*/
int pthread_key_delete(pthread_key_t key);

1.5 线程同步

同步的方式,主要包含,互斥锁,条件变量,异步信号。

互斥锁

#include 

/*锁的属性
* PTHREAD_MUTEX_TIMED_NP 普通锁,加锁后,形成等待队列
* PTHREAD_MUTEX_RECURSIVE_NP 嵌套锁,允许同一线程多次加锁,多次解锁;
* PTHREAD_MUTEX_ERRORCHECK_NP 检错锁,同一线程,请求同一个锁,返回EDEADLK;
* PTHREAD_MUTEX_ADAPTIVE_NP 适应锁,解锁后,重新竞争
*/


/*初始化锁*/
pthread_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);

/*或加锁,若已被锁,则立即返回busy*/
int pthread_mutex_trylock(pthread_mutex_t *mutex);

/*解锁*/
int pthread_mutex_unlock(pthread_mutex_t *mutex);

/*清除互斥锁,解锁后,才能清除成功*/
int pthread_mutex_destroy(pthread_mutex_t *mutex);


条件变量

#include 

/*初始化条件变量*/
pthread_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);

异步信号

#include 

/*向特定线程,发送信号*/
int 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 信号种类

[linux专题]基于linux线程与信号处理_第1张图片

信号 说明
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);                       /*
#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 SIGINT\n");
    sleep(5);
    tmp++;
    printf("tmp value is %d \n",tmp);
}

执行以上程序,按CTRL+C 出现效果,按CTRL+\ 退出

#include 

/*使调用进程挂起,直到捕获到信号*/
int 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);

how,主要包含如下设置

SIG_BLOCK,设置为信号集并集 set| oldset

SIG_SETMASK,设置为set

int sigpending(sigset_t *set);

获取当点pending的信号集

int sigsuspend(const sigset_t *mask)

将信号屏蔽码设置为mask,和pause一样,等待信号的发生并执行信号处理函数。

你可能感兴趣的:(Linux,自动驾驶,linux,线程,信号)