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多次,父子进程分别有一半的机会得到锁。但后来运行同样次数,却老是父进程得到。莫名其妙,还跟《高级编程环境》里说的不一样。