本教程不是基础线程,希望有点基础的POSIX 线程知识。 高手也不用看了。。
第一篇:Linux线程的信号处理行为
大家都知道linux 2.5内核之后 引入了NPTL ,让自己的用户态线程行为更符合Poxis口味。。下面就来看看NPTL的线程对信号的行为。
当然我们得首先复习..几个linux上的函数
tkill
NAME tkill
- send a signal to a single process SYNOPSIS int tkill(int tid, int sig);
DESCRIPTION
The tkill() system call is analogous to kill(2), except when the specified process is part of a thread group (created by specifying the CLONE_THREAD flag in the call to clone). Since all the processes in a thread group have the same PID, they cannot be individually sig-nalled with kill(2). With tkill(), however, one can address each process by its unique TID.These are the raw system call interfaces, meant for internal thread library use.
我个人感觉这个man写的不怎么好: 因为你不能把他翻译成中文去理解
通俗易懂的说: tkill 可以发给特定的 LWP,比如一个进程,他产生了很多LWP, 那么我可以想发给谁发给谁。
如果他不产生,就他一个独苗,那么我用tikll对他发信号,和kill发效果是一样的。
我们都知道如果通过kill 发信号给一个PID ,如果你没有做什么的话,正常情况下,应该是main线程接受。这个时候你会想,太搓了! 我要把信号发给我指定的人!
好linux知道你有这个怪癖,提供了tkill。 问题来了 tid是啥。。2.6内核proc下面看不到了!当然你可以猜:
现在的进程是 PID, 那么我产生的应该是 PID+1,但是当你产生了1000个,就找不到北了。。
linux当然早提供了gettid ,你可能需要通过
syscall(SYS_gettid);
记住 pthread_self 得到是线程自己的一个pthread_t ,这个玩意内核是没有数据结构记录的,应该只是一个用户态的东东,对他发信号,只需要 pthread_kill();
这个时候,你是不是开始跃跃欲试的,想试试看 tkill了? 于是你会这样写
测试进程:
static void* is_receive(void* arg)
{
while(1) {
printf("%d LWP RUNNING\n",
syscall(SYS_gettid); );
sleep(5);
}
return (void*)(-1);
}
int main(int argc, char *argv[])
{
pthread_t t;
pthread_attr_t prattr;
pthread_attr_init(&prattr);
pthread_attr_setdetachstate(&prattr,
PTHREAD_CREATE_JOINABLE);
pthread_attr_setscope(&prattr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&t, &prattr, is_receive, NULL);
pause();
}
然后很开心的用
syscall(__NR_tkill, tid, SIGUSR1);
发送完了,你ps -ef一看,说,cao 。。不对啊,主线程也没了。
记住,如果你用任何测试信号的时候。 请记得他在 APUE书中写的默认行为 ,改整个进程退出的他们还是会退出,不是你发给 某个LWP,就可以改变Poxis的。。
所以你最好找那种默认行为为SIG_IGN的测试。。或者你自己之前改写了如SIGPIPE这样的信号行为。
于是你会得到你想要的结果。
然后你会说,我不想用tkill ,因为是custom 发信息给我。他不知道TID,只知道PID。这个时候你只能用kill(sigqueue)
于是谁去处理信号的问题,就需要你编程手动处理。
我们先来看看thread prime上怎么说:
我觉得T_P上面很多话都没用。 关于这个话题我提炼出一句话: 你需要发给哪个LWP ,把不需要的BLOCK就行!
代码看起来可能应该这样写。
void block_it(int sig)
{
sigset_t sig_block;
sigemptyset(&sig_block);
sigaddset( &sig_block, sig);
sigprocmask( SIG_BLOCK, &sig_block, NULL );
//pthread_sigmask( SIG_BLOCK, &sig_block, NULL );
}
static void* receive_signal(void* arg)
{
//block_it(SIGUSR2);
while(1) {
sleep(5);
}
return (void*)(-1);
}
static void just_printf(int arg){
printf("%d RECEIVING\n",syscall(SYS_gettid));
}
int main(int argc, char *argv[])
{
signal(SIGUSR2,just_printf);
int tid;
pthread_t t;
pthread_attr_t prattr;
pthread_attr_init(&prattr);
pthread_attr_setdetachstate(&prattr,PTHREAD_CREATE_JOINABLE);
pthread_attr_setscope(&prattr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&t, &prattr, receive_signal, NULL);
block_it(SIGUSR2);//让子线程接受信号
pause();
}
看到block_it 这个函数了吗? 没错。just do it, 在信号来之前赶快哦。 这样你用kill(getpid(),SIG___) 你会发现他们工作的很好。 就算你个pid发送,子线程也帮你处理了这个信号~。
方法告诉你了,具体几千个LWP怎么指派某一个,就要自己发挥想象啦。 P_T中告诉你。。你可以用一个专门的信号处理线程~~
同样你也可能看到注释掉的pthread_sigmask() 为啥呢。因为
The function shall be equivalent to sigprocmask(), without the restriction that the call be made in a single-threaded process.
大家考虑一下,怎么实现一个异步IO ?
>
>
>
>
没错 ,如果了解 softirq 的人 都知道通过 参考ksoftirqd 线程
A: dedicated kernel<use process> thread ; B : work queues 在加上上面说的唤醒锁机制 就ok 啦
- 大小: 28.1 KB
分享到:
相关推荐
嵌入式Liunx应用程序开发笔记-代码.zip嵌入式Liunx应用程序开发笔记-代码.zip嵌入式Liunx应用程序开发笔记-代码.zip嵌入式Liunx应用程序开发笔记-代码.zip嵌入式Liunx应用程序开发笔记-代码.zip嵌入式Liunx应用程序...
- **SIGNAL.C程序**:解释了信号处理机制,包括信号的发送与接收。 - **EXIT.C程序**:分析了进程退出机制的实现细节。 - **FORK.C程序**:探讨了进程复制机制的实现,包括父子进程之间的关系。 - **SYS.C程序**:...
《MySQL数据库备份神器:mysqldump在Win、Linux及Mac平台的应用与实践》 MySQL作为全球最受欢迎的开源关系型数据库管理系统之一,其稳定性和高效性深受广大开发者的喜爱。在日常运维过程中,数据安全至关重要,这就...
liunx ftp服务器搭建
* 数据处理:使用 shell 脚本可以自动完成数据处理任务,例如数据备份和恢复。 Linux Shell 脚本编程是一种强大的编程语言,广泛应用于 Linux 操作系统中。通过学习和掌握 Linux Shell 脚本编程的知识点,可以提高...
pid_t fork(void)失败返回-1,成功返回:1。父进程返回子进程的ID 2.子进程返回0 pid_t类型表示进程ID,但为了表示-1,它是有符号整型笔记返回值,不是fork函数能返回两个值,或者fork后,fork函数变成两个,父子...
1. **SSH协议基础**:SSH协议分为两层,SSH连接协议和SSH传输协议。连接协议处理认证和加密,而传输协议则负责数据传输。SSH支持多种身份验证方式,包括密码、公钥私钥对、键盘交互式认证等,其中公钥认证是最安全的...
1. 下载:从Sonatype官网下载对应的Nexus版本,这里我们已经有了 "nexus-3.6.2-01-unix.tar.gz"。 2. 解压:在Linux服务器上找到一个合适的目录,使用`tar -zxvf nexus-3.6.2-01-unix.tar.gz`命令解压文件。 3. 配置...
- **共享资源**:同一进程内的所有线程共享进程的地址空间、文件描述符表、信号处理方式等资源。这意味着任何线程对这些资源的修改都会影响其他线程。 - **独立性**:进程之间是完全独立的,拥有自己的地址空间和...
离线安装包,亲测可用
LIUNX常用vsftpd-3.0.3的rpm包
1. **Oracle Instant Client的基本概念**:Oracle Instant Client是一个小型的、易于部署的客户端软件,它允许应用程序在不安装完整Oracle数据库的情况下连接到Oracle数据库服务器。它主要包含了一系列动态链接库...
1. 更新系统软件库:在大多数Linux发行版中,首先需要确保系统软件库是最新的。你可以使用`sudo apt-get update`(对于基于Debian的系统)或`yum update`(对于基于RPM的系统)来更新。 2. 安装Samba软件包:接下来...
在这个项目中,C语言用于控制DYP-ME007模块的Trig和Echo引脚,发送超声波脉冲并接收回波信号,进而计算出距离。 四、程序实现 1. 超声波发送:通过设置Trig引脚输出高电平脉冲(至少10us),启动超声波发射。 2. ...
1. `bin`:包含启动、停止和管理Tomcat的脚本,如`catalina.sh`用于启动和关闭Tomcat,`startup.sh`和`shutdown.sh`是这两个功能的简化版本。 2. `conf`:配置文件的存放地,包括`server.xml`(定义服务器的全局...
Nexus是Sonatype公司开发的一款强大的仓库管理器,主要用于管理和分发Maven、npm、Gradle等构建工具的依赖库。Nexus 3.7.1-02是该软件的一个Linux版本,它包含了对Maven项目的特别支持,因为“Nexus Maven”标签明确...
Apache Flink是一个流行的开源流处理和批处理框架,主要用于实时数据处理。Flink 1.11.2是该项目的一个稳定版本,它包含了各种优化和改进,以提供更高效、可靠的数据流处理能力。该版本支持Scala 2.12,这是一种广泛...
docker-compose liunx(64) 和 window(64)两个版本 构建版本 docker-compose version 1.25.4, build 8d51620a
mariadb老版数据库下载资源安装包,应对旧系统框架不支持新版数据库。
1. **获取软件包**:提供的文件"rp-pppoe-3.6"可能是一个RPM软件包,这是Red Hat和其兼容系统常用的软件包格式。用户需要先下载这个文件。 2. **安装软件包**:在命令行中,可以使用`rpm`命令来安装RPM包,例如`...