Linux-linux内核如何判断进程间发生死锁

Linux-linux内核如何判断进程间发生死锁

晚风撩人 发布于 2017-06-06 字数 1995 浏览 1022 回复 3

在学习APUE有关记录锁的章节时,遇到一个死锁的问题:(为了便于讨论,修改作者提供的代码)

 #include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

#define writew_lock(fd, offset, whence, len)
lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))

int
lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
{
struct flock lock;

lock.l_type = type; /* F_RDLCK, F_WRLCK, F_UNLCK */
lock.l_start = offset; /* byte offset, relative to l_whence */
lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
lock.l_len = len; /* #bytes (0 means to EOF) */

return(fcntl(fd, cmd, &lock));
}

static void
lockabyte(const char *name, int fd, off_t offset)
{
if (writew_lock(fd, offset, SEEK_SET, 1) < 0)
{
fprintf(stderr, "%s: writew_lock errorn", name);
exit(-1);
}
printf("%s: got the lock, byte %ldn", name, offset);
}

int main()
{
int fd;
pid_t pid;

if ((fd=creat("tmpfile", FILE_MODE)) < 0)
{
fprintf(stderr, "create file failed!n");
exit(-1);
}
if (write(fd, "ab", 2)!=2)
{
fprintf(stderr, "write file failedn");
exit(-1);
}

sleep(1);

if ((pid = fork()) < 0)
{
fprintf(stderr, "fork failed!n");
exit(-1);
}
else if(pid == 0)
{
// child
lockabyte("child", fd, 0);
sleep(2);
lockabyte("child", fd, 1);
}
else
{
lockabyte("parent", fd, 1);
sleep(2);
lockabyte("parent", fd, 0);
}

exit(0);
}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清晨说ぺ晚安 2017-08-25 3 楼

程序中使用多个互斥量时,如果允许一个线程(进程)一直占有第一个互斥量,并且在试图锁住第二个互斥量时处于阻塞状态,但是拥有第二个互斥量的线程(进程)也试图想锁住第一个互斥量,这时谁都在互相请求各自的资源而无法向前运行,于是就产生了死锁!

归属感 2017-08-07 2 楼

死锁形成的原因是不同进程所持有和申请的锁形成了一个环,出现死锁一般表明程序代码中有bug。
在Linux内核中,为了避免死锁,有几条措施:
1 spin lock获得后不会发生进程调度;
2 获取多把spin lock时,所有进程按照锁的地址大小顺序获取;
3 要使用多个锁的子系统中,对各种锁的使用会形成一个获取顺序的约定,(可参考mm/rmap.c)
4 Linux内核中有一个nmi不可屏蔽中断,如果系统发现关中断时间过长,就会认为发生了死锁,触发这个中断。当然这种措施并不能发现那些未关中断获取的锁导致的死锁。

想挽留 2017-07-30 1 楼

Linux内核中有一个nmi不可屏蔽中断,如果系统发现关中断时间过长,就会认为发生了死锁,触发这个中断。