红联Linux门户
Linux帮助

Linux操作系统系统下的死锁研究

发布时间:2006-12-10 11:39:49来源:红联作者:download
相关函数:
fcntl(),信号系列(在这不是讨论的重点)
相关数据结构
struct flock
{
...
short l_type; /* Type of lock: F_RDLCK,
F_WRLCK, F_UNLCK */
short l_whence; /* How to interpret l_start:
SEEK_SET, SEEK_CUR, SEEK_END */
off_t l_start; /* Starting offset for lock */
off_t l_len; /* Number of bytes to lock */
pid_t l_pid; /* PID of process blocking our lock
(F_GETLK only) */
...
};

代码:
#include
#include
#include
#include
#include
#include

#define FORPAR 0
#define FORCHD 1
#define PARSNT SIGUSR1
#define CHDSNT SIGUSR2

#define TESTFILE "/dev/shm/test"

int
main ()
{
void wake (); //wake up function
struct flock lock;
int fd;
sigset_t set;
pid_t pid;

//---------create a file
if ((fd = open (TESTFILE, O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1)
{
perror ("open() fail");
exit (1);
}

write (fd, "abcd", 2);

//-------setting the lock
lock.l_whence = SEEK_SET;
lock.l_len = 1;
lock.l_type = F_WRLCK;

//-------setting the signal set
sigfillset (&set);
sigdelset (&set, SIGINT);
if (sigprocmask (SIG_SETMASK, &set, NULL) == -1)
{
perror ("setting mask fail");
exit (1);
}

if ((pid = fork ()) == 0)
{
lock.l_start = FORCHD;
if (fcntl (fd, F_SETLKW, &lock) == -1)
{
perror ("setting lock fail...");
exit (1);
}
else
// puts ("Child: I have lock my own part!");

signal (PARSNT, wake); //handle parent's signal
kill (getppid (), CHDSNT); //telling parent that his has done his job
sigdelset (&set, PARSNT);
sigsuspend (&set); //waiting for parent's information;

lock.l_start = FORPAR; //to lock the parent's part
if (fcntl (fd, F_SETLKW, &lock) == -1)
{
perror ("child: setting lock fail...");
#ifndef DEBUG
exit (1);
#endif
}
else
puts ("Suceed to lock parent's part...");

_exit (0);
}


//parent----------------------------
lock.l_start = FORPAR;
if (fcntl (fd, F_SETLKW, &lock) == -1)
{
perror ("setting lock fail...");
exit (1);
}
else
// puts ("Parent: I have lock my own part!");

signal (CHDSNT, wake); //handle child's signal
kill (pid, PARSNT); //telling child that his has done his job
sigdelset (&set, CHDSNT);
sigsuspend (&set); //waiting for child's information;

lock.l_start = FORCHD;
if (fcntl (fd, F_SETLKW, &lock) == -1)
{
perror ("parent: setting lock fail...");
#ifndef DEBUG
exit (1);
#endif
}
else
puts ("Suceed to lock child's part...");

return 0;
}

void
wake ()
{
return;
}

运行结果:
[sody@longtem exercise]$ ./a.out
child: setting lock fail...: Resource deadlock avoided
Suceed to lock child's part...
[sody@longtem exercise]$ ./a.out
child: setting lock fail...: Resource deadlock avoided
Suceed to lock child's part...
[sody@longtem exercise]$ ./a.out
child: setting lock fail...: Resource deadlock avoided
Suceed to lock child's part...
[sody@longtem exercise]$ ./a.out
child: setting lock fail...: Resource deadlock avoided
Suceed to lock child's part...

测试的结果有点奇怪。因为我有一次是狂运行了1000多次,父子进程分别有一半的机会得到锁。但后来运行同样次数,却老是父进程得到。莫名其妙,还跟《高级编程环境》里说的不一样。
文章评论

共有 0 条评论