以下是 Linux 进程状态;
R: running or runnable, it is just waiting for the CPU to process it
S: Interruptible sleep, waiting for an event to complete, such as input from the terminal
D: Uninterruptible sleep, processes that cannot be killed or interrupted with a signal, usually to make them go away you have to reboot or fix the issue
Z: Zombie, we discussed in a previous lesson that zombies are terminated processes that are waiting to have their statuses collected
T: Stopped, a process that has been suspended/stopped
我有两个问题;
(1) 当进程/线程中调用 mutex_lock() 时,如果正在等待锁获取(另一个线程已经锁定了互斥锁),进程会转到S
orD
吗?
(2) 我知道 spinlock() 会将进程置于忙等待状态,并检查锁是否已被其他线程解锁。但是,在 mutex_lock() 中,它如何知道锁已解锁并且可以锁定并继续? IE;sleep
当互斥体可用时(被其他线程解锁),进程如何从锁定互斥体中唤醒?
答案1
好吧,让我们来了解一下:
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main ()
{
pthread_mutex_t mtx;
pid_t pid;
pthread_mutex_init (&mtx, NULL);
pid = getpid();
printf ("pid : %d\n", pid);
pthread_mutex_lock (&mtx);
// Double lock. This results in a dead-lock
pthread_mutex_lock (&mtx);
pthread_mutex_destroy (&mtx);
}
编译:
gcc -lpthread -o prog prog.c
然后运行:
./prog
pid : 23537
(这是我的特定情况下的 pid。您的运行将导致不同的结果)
现在让我们看看这个过程的状态:
ps aux | grep 23537
user 23537 0.0 0.0 6448 840 pts/4 S+ 16:29 0:00 ./prog
这S+是进程的状态。
根据手册页
PROCESS STATE CODES
Here are the different values that the s, stat and state output specifiers (header "STAT" or "S") will display to describe the state of a
process:
D uninterruptible sleep (usually IO)
R running or runnable (on run queue)
S interruptible sleep (waiting for an event to complete)
T stopped by job control signal
t stopped by debugger during the tracing
W paging (not valid since the 2.6.xx kernel)
X dead (should never be seen)
Z defunct ("zombie") process, terminated but not reaped by its parent
For BSD formats and when the stat keyword is used, additional characters may be displayed:
< high-priority (not nice to other users)
N low-priority (nice to other users)
L has pages locked into memory (for real-time and custom IO)
s is a session leader
l is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
+ is in the foreground process group
原来如此前台进程组中的可中断睡眠(等待事件完成)
关于第二个问题:当一个线程尝试获取已锁定的互斥锁时,内核会从 CPU 中删除该线程并将其存储在队列中。当所有者释放锁时,内核会查找队列中是否有任何线程,并唤醒它们(也许)。
这与自旋锁不同。自旋锁类似于:
int lock = 1;
// 1 means locked, 0 means unlocked
while (lock) {};
// If we are here, it means the lock somehow changed to 0
lock = 1;
// We set it to one again to avoid another thread taking it
但这个实现不是原子的。内核提供了一些以原子方式完成此操作的方法。