Ⅰ JVM线程与linux内核线程的映射(关系)
Linux从内核2.6开始使用NPTL(Native POSIX Thread Library)支持,但这时线程本质上还轻量级进程。 Native POSIX Thread Library(NPTL)是Linux内核中实践POSIX Threads标准的库。POSIX线程(英语:POSIX Threads,常被缩写为Pthreads)是POSIX的线程标准,定义了创建和操纵线程的一套API。实现POSIX 线程标准的库常被称作Pthreads
Pthreads定义了一套C语言的类型、函数与常量,它以pthread.h头文件和一个线程库实现。
Pthreads API中大致共有100个函数调用,全都以"pthread_"开头,并可以分为四类:
线程管理,例如创建线程,等待(join)线程,查询线程状态等。
互斥锁(Mutex):创建、摧毁、锁定、解锁、设置属性等操作
条件变量(Condition Variable):创建、摧毁、等待、通知、设置与查询属性等操作
使用了互斥锁的线程间的同步管理
Java里的线程是由JVM来管理的,它如何对应到操作系统的线程是由JVM的实现来确定的。Linux 2.6上的HotSpot使用了NPTL机制, JVM线程跟内核轻量级进程有一一对应的关系 。线程的调度完全交给了操作系统内核,当然jvm还保留一些策略足以影响到其内部的线程调度,举个例子,在linux下,只要一个Thread.run就会调用一个fork产生一个线程。
Java线程在Windows及Linux平台上的实现方式,现在看来,是内核线程的实现方式。这种方式实现的线程,是直接由操作系统内核支持的——由内核完成线程切换,内核通过操纵调度器(Thread Scheler)实现线程调度,并将线程任务反映到各个处理器上。内核线程是内核的一个分身。程序一般不直接使用该内核线程,而是使用其高级接口,即轻量级进程
创建用户级线程
Ⅱ linux中查看进程命令ps aux和ps -ef
Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux。这两个到底有什么区别呢?两者没太大差别,讨论这个问题,要追溯到Unix系统中的两种风格,System V风格和BSD 风格,ps aux最初用到Unix Style中,而ps -ef被用在System V Style中,两者输出略有不同。现在的大部分Linux系统都是可以同时使用这两种方式的。
ps -ef 是用标准的格式显示进程的、其格式如下:
其中各列的内容意思如下
UID //用户ID、但输出的是用户名
PID //进程的ID
PPID //父进程ID
C //进程占用CPU的百分比
STIME //进程启动到现在的时间
TTY //该进程在那个终端上运行,若与终端无关,则显示? 若为pts/0等,则表示由网络连接主机进程。
CMD //命令的名称和参数
ps aux 是用BSD的格式来显示、其格式如下:
同ps -ef 不同的有列有
USER //用户名
%CPU //进程占用的CPU百分比
%MEM //占用内存的百分比
VSZ //该进程使用的虚拟内存量(KB)
RSS //该进程占用的固定内存量(KB)(驻留中页的数量)
STAT //进程的状态
START //该进程被触发启动时间
TIME //该进程实际使用CPU运行的时间
其中STAT状态位常见的状态字符有
D //无法中断的休眠状态(通常 IO 的进程); uninterruptible sleep (usually IO)不可中断
R //正在运行可中在队列中可过行的;
S //处于休眠状态;
T //停止或被追踪; traced or stopped
W //进入内存交换 (从内核2.6开始无效);
X //死掉的进程 (基本很少见);
Z //僵尸进程; a defunct (”zombie”) process
< //优先级高的进程
N //优先级较低的进程
L //有些页被锁进内存;
s //进程的领导者(在它之下有子进程);
l //多线程,克隆线程(使用 CLONE_THREAD, 类似 NPTL pthreads);
+ //位于后台的进程组;
Ⅲ linux pthread 信号量 占用资源吗
glibc提供的pthread互斥信号量可以用在进程内部,也可以用在进程间,可以在初始化时通过pthread_mutexattr_setpshared接口设置该信号量属性,表示是进程内还是进程间。进程内的使用较为简单,本文的总结主要是针对进程间的,进程内的也可以参考,其代码实现原理是类似的。
一、实现原理
pthread mutex的实现是非常轻量级的,采用原子操作+futex系统调用。
在没有竞争的情况下,即锁空闲时,任务获取信号量只需要通过原子操作锁的状态值,把值置为占有,再记录其他一些俄信息(owner,计数,如果使能回收功能则串入任务的信号量回收链表等),然后就返回了。
如果在获取锁时发现被占用了,如果调用者需要睡眠等待,这时候会触发futex系统调用,由内核继续处理,内核会让调用任务睡眠,并在适当时候唤醒(超时或者锁状态为可用)。
占用锁的任务释放锁时,如果没有任务等待这把锁,只需要把锁状态置为空闲即可。如果发现有其他任务在等待此锁,则触发futex系统调用,由内核唤醒等待任务。
由此可见,在没有竞争的情况下,mutex只需要在用户态操作锁状态值,无须陷入内核,是非常高效的。
获取到锁的任务没有陷入内核,那么当锁支持优先级翻转时,高优先级任务等待这把锁,正常处理必须提升占用锁的任务优先级。内核又是怎么知道是哪个任务占用了锁呢?实现上,复用了锁的状态值,该值在空闲态时为0,非空闲态则保存了锁的持有者ID,即PID,内核态通过PID就知道是那个任务了。
二、内核对锁的管理
内核维护了一个hash链表,每把锁都被插入到hash链表中去,hash值的计算如下(参考get_futex_key):1,如果是进程内的锁,则通
过锁的虚拟地址+任务mm指针值+锁在页内偏移;2,如果是进程间的锁,则会获取锁虚拟地址对应物理地址的page描述符,由page描述符构造
hash值。
这样计算的原因是进程间的锁在各个进程内虚拟地址可能是不同的,但都映射到同一个物理地址,对应同一个page描述符。所以,内
核使用它来定位是否同一个锁。
这里对进程间互斥锁计算hash值的方法,给进程间共享锁的使用设置了一个隐患条件。下面描述这个问题。
三、进程间互斥信号量的使用限制:必须在系统管理的内存上定义mutex结构,而不能在用户reserved的共享内存上定义mutex结构。
锁要实现进程间互斥,必须各个进程都能看到这个锁,因此,锁结构必须放在共享内存上。
获取系统的共享内存通过System V的API接口创建:shmget, shmat,shmdt。但是shmget的参数需要一个id值,各进程映射同一块共享内存需要同样的ID值。如果各个进程需要共享的共享内存比较多,如几千上万个,ID值如果管理?shmget的man帮助和一些示例代码给出的是通过ftok函数把一个文件转为ID值(实际就是把文件对应的INODE转为ID值),但实际应用中,如果需要的共享内存个数较多,难道创建成千上万个文件来使用?而且怎么保证文件在进程的生命周期内不会被删除或者重建?
当时开发的系统还存在另外一种共享内存,就是我们通过remap_pfn_range实现的,自己管理了这块内存的申请释放。申请接口参数为字符串,相同的字符串表示同一块内存。因此,倾向于使用自己管理的共享内存存放mutex结构。但在使用中,发现这种方法达不到互斥的效果。为什么?
原因是自己管理的共享内存在内核是通过remap_pfn_range实现的,内核会把这块内存置为reserved,表示非内核管理,获取锁的HASH值时,查找不到page结构,返回失败了。最后的解决方法还是通过shmget申请共享内存,但不是通过ftok获取ID,而是通过字符串转为ID值并处理冲突。
四、进程间互斥信号量回收问题。
假设进程P1获取了进程间信号量,异常退出了,还没有释放信号量,这时候其他进程想来获取信号量,能获取的到吗?
或者进程P1获取了信号量后,其他进程获取不到进入了睡眠后,P1异常退出了,谁来负责唤醒睡眠的进程?
好在系统设计上已经考虑了这一点。
只要在信号量初始化时调用pthread_mutexattr_setrobust_np设置支持信号量回收机制,然后,在获取信号量时,如果原来占有信号量的进程退出了,系统将会返回EOWNERDEAD,判断是这个返回值后,调用pthread_mutex_consistent_np完成信号量owner的切换工作即可。
其原理如下:
任务创建时,会注册一个robust list(用户态链表)到内核的任务控制块TCB中期,获取了信号量时,会把信号量挂入链表。进程复位时,内核会遍历此链表(内核必须非常小心,因为此时的链表信息可能不可靠了,可不能影响到内核),置上ownerdead的标志到锁状态,并唤醒等待在此信号量链表上的进程。
五、pthread接口使用说明
pthread_mutex_init: 根据指定的属性初始化一个mutex,状态为空闲。
pthread_mutex_destroy: 删除一个mutex
pthread_mutex_lock/trylock/timedlock/unlock: 获取锁、释放锁。没有竞争关系的情况下在用户态只需要置下锁的状态值即返回了,无须陷入内核。但是timedlock的入参为超时时间,一般需要调用系统API获取,会导致陷入内核,性能较差,实现上,可先trylock,失败了再timedlock。
pthread_mutexattr_init:配置初始化
pthread_mutexattr_destroy:删除配置初始化接口申请的资源
pthread_mutexattr_setpshared:设置mutex是否进程间共享
pthread_mutexattr_settype:设置类型,如递归调用,错误检测等。
pthread_mutexattr_setprotocol:设置是否支持优先级翻转
pthread_mutexattr_setprioceiling:设置获取信号量的任务运行在最高优先级。
每个set接口都有对应的get接口。
六、pthread结构变量说明
struct __pthread_mutex_s
{
int __lock; ----31bit:这个锁是否有等待者;30bit:这个锁的owner是否已经挂掉了。其他bit位:0锁状态空闲,非0为持有锁的任务PID;
unsigned int __count; ----获取锁的次数,支持嵌套调用,每次获取到锁值加1,释放减1。
int __owner; ----锁的owner
unsigned int __nusers; ----使用锁的任务个数,通常为1(被占用)或0(空闲)
int __kind;----锁的属性,如递归调用,优先级翻转等。
int __spins; ----SMP下,尝试获取锁的次数,尽量不进入内核。
__pthread_list_t __list; ----把锁插入回收链表,如果支持回收功能,每次获取锁时要插入任务控制块的回收链表。
}__data;
Ⅳ Linux 权能综述
为了执行权限检查,传统的 UNIX 实现区分两种类型的进程:特权进程(其有效用户 ID 为0,称为超级用户或 root),和非特权用户(其有效 UID 非0)。特权进程绕过所有的内核权限检查,而非特权进程受基于进程的认证信息(通常是:有效 UID,有效 GID,和补充组列表)的完整权限检查的支配。
自内核 2.2 版本开始,Linux 将传统上与超级用户关联的特权分为几个单元,称为 capabilities (权能),它们可以被独立的启用或禁用。权能是每个线程的属性。
下面的列表展示了 Linux 上实现的权能,以及每种权能允许的操作或行为:
权能的完整实现需要:
在内核 2.6.24 之前,只有前两个要求能够满足;自内核 2.6.24 开始,所有三个要求都能满足。
每个线程具有三个包含零个或多个上面的权能的权能集合:
A child created via fork(2) inherits copies of its parent's capability sets. See below for a discussion of the treatment of capabilities ring execve(2).
Using capset(2), a thread may manipulate its own capability sets (see below).
Since Linux 3.2, the file /proc/sys/kernel/cap_last_cap exposes the numerical value of the highest capability supported by the running kernel; this can be used to determine the highest bit that may be set in a capability set.
Since kernel 2.6.24, the kernel supports associating capability sets with an executable file using setcap(8). The file capability sets are stored in an extended attribute (see setxattr(2)) named security.capability. Writing to this extended attribute requires the CAP_SETFCAP capability. The file capability sets, in conjunction with the capability sets of the thread, determine the capabilities of a thread after an execve(2).
The three file capability sets are:
During an execve(2), the kernel calculates the new capabilities of the process using the following algorithm:
其中:
A privileged file is one that has capabilities or has the set-user-ID or set-group-ID bit set.
In order to provide an all-powerful root using capability sets, ring an execve(2):
The upshot of the above rules, combined with the capabilities transformations described above, is that when a process execve(2)s a set-user-ID-root program, or when a process with an effective UID of 0 execve(2)s a program, it gains all capabilities in its permitted and effective capability sets, except those masked out by the capability bounding set. This provides semantics that are the same as those provided by traditional UNIX systems.
The capability bounding set is a security mechanism that can be used to limit the capabilities that can be gained ring an execve(2). The bounding set is used in the following ways:
Note that the bounding set masks the file permitted capabilities, but not the inherited capabilities. If a thread maintains a capability in its inherited set that is not in its bounding set, then it can still gain that capability in its permitted set by executing a file that has the capability in its inherited set.
Depending on the kernel version, the capability bounding set is either a system-wide attribute, or a per-process attribute.
In kernels before 2.6.25, the capability bounding set is a system-wide attribute that affects all threads on the system. The bounding set is accessible via the file /proc/sys/kernel/cap-bound. (Confusingly, this bit mask parameter is expressed as a signed decimal number in /proc/sys/kernel/capbound.)
Only the init process may set capabilities in the capability bounding set; other than that, the superuser (more precisely: programs with the CAP_SYS_MODULE capability) may only clear capabilities from this set.
On a standard system the capability bounding set always masks out the CAP_SETPCAP capability. To remove this restriction (dangerous!), modify the definition of CAP_INIT_EFF_SET in include/linux/capability.h and rebuild the kernel.
The system-wide capability bounding set feature was added to Linux starting with kernel version 2.2.11.
From Linux 2.6.25, the capability bounding set is a per-thread attribute. (There is no longer a systemwide capability bounding set.)
The bounding set is inherited at fork(2) from the thread's parent, and is preserved across an execve(2).
A thread may remove capabilities from its capability bounding set using the prctl(2) PR_CAPBSET_DROP operation, provided it has the CAP_SETPCAP capability. Once a capability has been dropped from the bounding set, it cannot be restored to that set. A thread can determine if a capability is in its bounding set using the prctl(2) PR_CAPBSET_READ operation.
Removing capabilities from the bounding set is supported only if file capabilities are compiled into the kernel. In kernels before Linux 2.6.33, file capabilities were an optional feature configurable via the CONFIG_SECURITY_FILE_CAPABILITIES option. Since Linux 2.6.33, the configuration option has been removed and file capabilities are always part of the kernel. When file capabilities are compiled into the kernel, the init process (the ancestor of all processes) begins with a full bounding set. If file capabilities are not compiled into the kernel, then init begins with a full bounding set minus CAP_SETPCAP, because this capability has a different meaning when there are no file capabilities.
Removing a capability from the bounding set does not remove it from the thread's inherited set. However it does prevent the capability from being added back into the thread's inherited set in the future.
To preserve the traditional semantics for transitions between 0 and nonzero user IDs, the kernel makes the following changes to a thread's capability sets on changes to the thread's real, effective, saved set, and filesystem user IDs (using setuid(2), setresuid(2), or similar):
If a thread that has a 0 value for one or more of its user IDs wants to prevent its permitted capability set being cleared when it resets all of its user IDs to nonzero values, it can do so using the prctl(2) PR_SET_KEEPCAPS operation or the SECBIT_KEEP_CAPS securebits flag described below.
A thread can retrieve and change its capability sets using the capget(2) and capset(2) system calls. However, the use of cap_get_proc(3) and cap_set_proc(3), both provided in the libcap package, is preferred for this purpose. The following rules govern changes to the thread capability sets:
Starting with kernel 2.6.26, and with a kernel in which file capabilities are enabled, Linux implements a set of per-thread securebits flags that can be used to disable special handling of capabilities for UID 0 (root). These flags are as follows:
Each of the above "base" flags has a companion "locked" flag. Setting any of the "locked" flags is irreversible, and has the effect of preventing further changes to the corresponding "base" flag. The locked flags are: SECBIT_KEEP_CAPS_LOCKED, SECBIT_NO_SETUID_FIXUP_LOCKED, SECBIT_NOROOT_LOCKED, and SECBIT_NO_CAP_AMBIENT_RAISE.
The securebits flags can be modified and retrieved using the prctl(2) PR_SET_SECUREBITS and PR_GET_SECUREBITS operations. The CAP_SETPCAP capability is required to modify the flags.
The securebits flags are inherited by child processes. During an execve(2), all of the flags are preserved, except SECBIT_KEEP_CAPS which is always cleared.
An application can use the following call to lock itself, and all of its descendants, into an environment where the only way of gaining capabilities is by executing a program with associated file capabilities:
For a discussion of the interaction of capabilities and user namespaces, see user_namespaces(7).
No standards govern capabilities, but the Linux capability implementation is based on the withdrawn POSIX.1e draft standard; see ⟨ http://wt.tuxomania.net/publications/posix.1e/ ⟩.
From kernel 2.5.27 to kernel 2.6.26, capabilities were an optional kernel component, and can be enabled/disabled via the CONFIG_SECURITY_CAPABILITIES kernel configuration option.
The /proc/PID/task/TID/status file can be used to view the capability sets of a thread. The /proc/PID/status file shows the capability sets of a process's main thread. Before Linux 3.8, nonexistent capabilities were shown as being enabled (1) in these sets. Since Linux 3.8, all nonexistent capabilities (above CAP_LAST_CAP) are shown as disabled (0).
The libcap package provides a suite of routines for setting and getting capabilities that is more comfortable and less likely to change than the interface provided by capset(2) and capget(2). This package also provides the setcap(8) and getcap(8) programs. It can be found at ⟨ http://www.kernel.org/pub/linux/libs/security/linux-privs ⟩.
Before kernel 2.6.24, and from kernel 2.6.24 to kernel 2.6.32 if file capabilities are not enabled, a thread with the CAP_SETPCAP capability can manipulate the capabilities of threads other than itself. However, this is only theoretically possible, since no thread ever has CAP_SETPCAP in either of these cases:
capsh(1), setpriv(1), prctl(2), setfsuid(2), cap_clear(3), cap__ext(3), cap_from_text(3), cap_get_file(3), cap_get_proc(3), cap_init(3), capgetp(3), capsetp(3), libcap(3), credentials(7), user_namespaces(7), pthreads(7), getcap(8), setcap(8)
include/linux/capability.h in the Linux kernel source tree
This page is part of release 4.04 of the Linux man-pages project. A description of the project, information about reporting bugs, and the latest version of this page, can be found at http://www.kernel.org/doc/man-pages/ .
Ⅳ linux nspr thread 和c的pthread库有什么区别
are/pthreads-win32/上可以查看pthread的相关介绍和信息,也可以下载pthread/pub/pthreads-win32/ 最新的dll,库,头文件和管理文档 DLLs, LIBs, header files, and admin documentation ftp://sourceware.org/pub/pthreads-win32/dll-latest/
Ⅵ linux 进程的查看使用什么命令
查看进程的命令有ps、pstree、pgrep等
1、ps
显示进程信息,参数可省略
-aux 以BSD风格显示进程
常用 -efH 以SystemV风格显示进程
-e , -A 显示所有进程
a 显示终端上所有用户的进程
x 显示无终端进程
u显示详细信息
f 树状显示
w 完整显示信息
l 显示长列表
各列输出字段的含义:
USER 进程所有者
PID 进程ID
PPID 父进程
%CPU CPU占用率
%MEM 内存占用率
NI 进程优先级。数值越大,占用CPU时间越少
VSZ 进程虚拟大小
RSS 页面文件占用
TTY 终端ID
STAT 进程状态
+---D 不可中断
Uninterruptible sleep (usually IO)
+---R 正在运行,或在队列中的进程
+---S 处于休眠状态
+---T 停止或被追踪
+---Z 僵尸进程
+---W 进入内存交换(从内核2.6开始无效)
+---X 死掉的进程
+---< 高优先级
+---N 低优先级
+---L 有些页被锁进内存
+---s 包含子进程
+---+ 位于后台的进程组;
+---l 多线程,克隆线程 multi-threaded (using CLONE_THREAD, like
NPTL pthreads do)
PID:进程标识符,系统为每一个进程分配一个识别码,称为PID。
ps命令极为常用,其他命令还有:
2.pstree
树状显示进程信息
-a 显示完整命令及参数
-c 重复进程分别显示
-c 显示进程ID、PID
-n 按 PID排列进程
3.pgrep<进程名>
显示进程的PID
-l 显示进程名和进程PID
-o 进程起始ID
-n 进程终止ID
Ⅶ 如何在Linux中统计一个进程的线程数
三种方法:1。 使用top命令,具体用法是 top -H 加上这个选项,top的每一行就不是显示一个进程,而是一个线程。
2。 使用ps命令,具体用法是 ps -xH 这样可以查看所有存在的线程,也可以使用grep作进一步的过滤。3。 使用ps命令,具体用法是 ps -mq PID 这样可以看到指定的进程产生的线程数目。更进一步,其实一些系统监控工具,在本质上也是读取的系统产生的文件罢了。比如说进程这个事情,现在假设有进程号为 5000 的进程,查看这个进程的所有具体信息,在哪查看呢?看看这个目录吧,/proc/5000/ 这里面有你所有想要的。其实stat代表着当前的一些信息。使用ps命令来查看进程的时候,进程状态分别对应的含义如下:D 不可中断睡眠 (通常是在IO操作) 收到信号不唤醒和不可运行, 进程必须等待直到有中断发生
R 正在运行或可运行(在运行队列排队中)
S 可中断睡眠 (休眠中, 受阻, 在等待某个条件的形成或接受到信号)
T 已停止的 进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行
W 正在换页(2.6.内核之前有效)
X 死进程 (未开启)
Z 僵尸进程 进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放BSD风格的
< 高优先级(not nice to other users)
N 低优先级(nice to other users)
L 页面锁定在内存(实时和定制的IO)
s 一个信息头
l 多线程(使用 CLONE_THREAD,像NPTL的pthreads的那样)+ 在前台进程组
Ⅷ linux qt 编译时与运行时缺乏共享库
LIBS += -L /usr/local/lib -levent -levent_core -levent_extra -levent_pthreads
/usr/local/lib 为lib库所在路径
-levent -levent_core -levent_extra -levent_pthreads为需要链接的库
缺少动态连接库.so--cannot open shared object file: No such file or directory
总结下来主要有3种方法:
ln -s /where/you/install/lib/*.so /usr/lib // -s选项不懂意思
sudo ldconfig //加载配置项? 用来刷新共享库缓存 详细请见: ldd和ldconfig命令2013-02-06
// 我是用第一种方法完成了修改 但是不太懂 sudo ldconfig 的意思 大概是加载配置项吧
export LD_LIBRARY_PATH=/where/you/install/lib:$LD_LIBRARY_PATH
sudo ldconfig
vim /etc/ld.so.conf
add /where/you/install/lib
sudo ldconfig
Ⅸ Linux下安装mathgl时出现Please install posix threads headers怎么办
posix threads是posix标准库中用于创建和管理线程的组件,又叫pthreads。在glibc标准库中就包含有libpthread。所以,你需要安装glibc,如果你已经安装了glibc还是提示这个,那应该是没有安装glibc-headers(我印象里安装glibc时会自动安装glibc-headers的)
Ⅹ linux 下查看进程用什么命令
linux 下查看进程可以使用的命令:
1、ps命令查找与进程相关的PID号:
2、ps a 显示现行终端机下的所有程序,包括其他用户的程序。
3、ps -A 显示所有程序。
4、ps c 列出程序时,显示每个程序真正的指令名称,而不包含路径,参数或常驻服务的标示。
5、ps -e 此参数的效果和指定"A"参数相同。
6、ps e 列出程序时,显示每个程序所使用的环境变量。
7、ps f 用ASCII字符显示树状结构,表达程序间的相互关系。
8、ps -H 显示树状结构,表示程序间的相互关系。
9、ps -N 显示所有的程序,除了执行ps指令终端机下的程序之外。
10、ps s 采用程序信号的格式显示程序状况。
11、ps S 列出程序时,包括已中断的子程序资料。
12、ps -t<终端机编号> 指定终端机编号,并列出属于该终端机的程序的状况。
13、ps u 以用户为主的格式来显示程序状况。
14、ps x 显示所有程序,不以终端机来区分。