`
sunzixun
  • 浏览: 75956 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Liunx NPTL 杂谈(1)--线程信号处理

阅读更多

本教程不是基础线程,希望有点基础的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应用程序开发笔记-代码.zip嵌入式Liunx应用程序...

    Liunx内核完全注释-1.9.5

    - **SIGNAL.C程序**:解释了信号处理机制,包括信号的发送与接收。 - **EXIT.C程序**:分析了进程退出机制的实现细节。 - **FORK.C程序**:探讨了进程复制机制的实现,包括父子进程之间的关系。 - **SYS.C程序**:...

    mysqldump-win-liunx-mac--v5.7

    《MySQL数据库备份神器:mysqldump在Win、Linux及Mac平台的应用与实践》 MySQL作为全球最受欢迎的开源关系型数据库管理系统之一,其稳定性和高效性深受广大开发者的喜爱。在日常运维过程中,数据安全至关重要,这就...

    liunx ftp服务器搭建-ppt

    liunx ftp服务器搭建

    liunx shell脚本编程-全网最全

    * 数据处理:使用 shell 脚本可以自动完成数据处理任务,例如数据备份和恢复。 Linux Shell 脚本编程是一种强大的编程语言,广泛应用于 Linux 操作系统中。通过学习和掌握 Linux Shell 脚本编程的知识点,可以提高...

    ARM-FOUR:Liunx系统编程--APUE

    pid_t fork(void)失败返回-1,成功返回:1。父进程返回子进程的ID 2.子进程返回0 pid_t类型表示进程ID,但为了表示-1,它是有符号整型笔记返回值,不是fork函数能返回两个值,或者fork后,fork函数变成两个,父子...

    liunx SSH SSHSecureShellClient-3.2.9 安装包

    1. **SSH协议基础**:SSH协议分为两层,SSH连接协议和SSH传输协议。连接协议处理认证和加密,而传输协议则负责数据传输。SSH支持多种身份验证方式,包括密码、公钥私钥对、键盘交互式认证等,其中公钥认证是最安全的...

    nexus-3.6.2-01-unix.tar.gz

    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多线程讲解

    - **共享资源**:同一进程内的所有线程共享进程的地址空间、文件描述符表、信号处理方式等资源。这意味着任何线程对这些资源的修改都会影响其他线程。 - **独立性**:进程之间是完全独立的,拥有自己的地址空间和...

    python-slip-dbus-0.4.0-4.el7.noarch.rpm

    离线安装包,亲测可用

    LIUNX常用vsftpd-3.0.3的rpm包

    LIUNX常用vsftpd-3.0.3的rpm包

    instantclient-basic-linux-11.2.0.3.0.zip

    1. **Oracle Instant Client的基本概念**:Oracle Instant Client是一个小型的、易于部署的客户端软件,它允许应用程序在不安装完整Oracle数据库的情况下连接到Oracle数据库服务器。它主要包含了一系列动态链接库...

    liunx上安装SamBa

    1. 更新系统软件库:在大多数Linux发行版中,首先需要确保系统软件库是最新的。你可以使用`sudo apt-get update`(对于基于Debian的系统)或`yum update`(对于基于RPM的系统)来更新。 2. 安装Samba软件包:接下来...

    DYP-ME007超声波测距模块8051应用源代码

    在这个项目中,C语言用于控制DYP-ME007模块的Trig和Echo引脚,发送超声波脉冲并接收回波信号,进而计算出距离。 四、程序实现 1. 超声波发送:通过设置Trig引脚输出高电平脉冲(至少10us),启动超声波发射。 2. ...

    liunx版apche-tomcat-6.0.48压缩包

    1. `bin`:包含启动、停止和管理Tomcat的脚本,如`catalina.sh`用于启动和关闭Tomcat,`startup.sh`和`shutdown.sh`是这两个功能的简化版本。 2. `conf`:配置文件的存放地,包括`server.xml`(定义服务器的全局...

    Nexus 3.7.1-02 Linux版本

    Nexus是Sonatype公司开发的一款强大的仓库管理器,主要用于管理和分发Maven、npm、Gradle等构建工具的依赖库。Nexus 3.7.1-02是该软件的一个Linux版本,它包含了对Maven项目的特别支持,因为“Nexus Maven”标签明确...

    flink-1.11.2-bin-scala_2.12 linux安装包

    Apache Flink是一个流行的开源流处理和批处理框架,主要用于实时数据处理。Flink 1.11.2是该项目的一个稳定版本,它包含了各种优化和改进,以提供更高效、可靠的数据流处理能力。该版本支持Scala 2.12,这是一种广泛...

    docker-compose-liunx-windows-64.rar

    docker-compose liunx(64) 和 window(64)两个版本 构建版本 docker-compose version 1.25.4, build 8d51620a

    mariadb数据库安装包

    mariadb老版数据库下载资源安装包,应对旧系统框架不支持新版数据库。

    pppoe server for linux

    1. **获取软件包**:提供的文件"rp-pppoe-3.6"可能是一个RPM软件包,这是Red Hat和其兼容系统常用的软件包格式。用户需要先下载这个文件。 2. **安装软件包**:在命令行中,可以使用`rpm`命令来安装RPM包,例如`...

Global site tag (gtag.js) - Google Analytics