日期:2014-05-16  浏览次数:20696 次

关于记录锁的struct flock结构中返回的pid问题

1.c
C/C++ code

/**************************************************************************************/
/*
        关于记录锁的struct flock结构中返回的pid问题
        返回的不是持有锁的那个进程ID吗?
  */
/*************************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "SynchroProcess.h"

int lock_reg(int fd, int cmd, int l_type, off_t l_start,
                 short where, off_t l_len)
{
    struct flock lock;
    
    lock.l_type = l_type;
    lock.l_whence = where;
    lock.l_start = l_start;
    lock.l_len = l_len;
    
    return fcntl(fd, cmd, &lock);
}

#define read_lock(fd, offset, where, len) \
            lock_reg(fd, F_SETLK, F_RDLCK, offset, where, len)
#define readw_lock(fd, offset, where, len) \
            lock_reg(fd, F_SETLKW, F_RDLCK, offset, where, len)            
#define write_lock(fd, offset, where, len) \
            lock_reg(fd, F_SETLK, F_WRLCK, offset, where, len)
#define writew_lock(fd, offset, where, len) \
            lock_reg(fd, F_SETLKW, F_WRLCK, offset, where, len)
#define un_lock(fd, offset, where, len) \
            lock_reg(fd, F_SETLK, F_UNLCK, offset, where, len)


pid_t lock_test(int fd, int type, off_t start,
                 short where, off_t len)
{
    struct flock lock;
        
    lock.l_type = type;
    lock.l_start = start;
    lock.l_whence = where;
    lock.l_len = len;
        
    if (fcntl(fd, F_GETFL, &lock) < 0)
    {
        printf("fcntl error!\n");
    }
    
    if (lock.l_type == F_UNLCK)
    {
        return 0;
    }
    
    return lock.l_pid;        
}

static void lockabyte(const char *name, int fd, off_t offset)
{
    if (writew_lock(fd, offset, SEEK_SET, 1) < 0)
    {
        printf("writew_lock error!\n");
    }
    
    printf("%s: got the lock, byte %ld\n", name, offset);
}
                 

int main()
{
    int fd;
    pid_t pid;
    
    if ((fd = creat("temp", O_RDWR )) < 0)
    {
        printf("creat error!\n");
    }
    
    if (write(fd, "ab", 2) != 2)
    {
        printf("write error!\n");
    }
    
    TELL_WAIT();
    if ((pid = fork()) < 0)
    {
        printf("fork error!\n");
    }
    else if (pid == 0)
    {
        printf("int child!\n");
        lockabyte("temp", fd, 0);
        TELL_PARENT(getppid());
        WAIT_PARENT();
        
    //返回的不是持有锁的那个进程ID吗?怎么不是父ID啊?
    printf("l_pid = %d ppid = %d  pid = %d\n", 
        lock_test(fd, F_GETFL, 1, SEEK_SET, 1), 
            getppid(), getpid());
        
        //lockabyte("temp", fd, 1);        //这里产生死锁。。。。
        TELL_PARENT(getppid());
    }
    else
    {
        WAIT_CHILD();
        printf("in parent!\n");
        lockabyte("temp", fd, 1);
        TELL_CHILD(pid);
        WAIT_CHILD();
    }
            
    
    return 0;
}

运行结果:
[root@localhost work1]# gcc *.c -o 1
[root@localhost work1]# ./1
int child!
temp: got the lock, byte 0
in parent!
temp: got the lock, byte 1
l_pid = 1104221896 ppid = 4788  pid = 4789                 //lock__pid返回的是什么啊?
[root@localhost work1]# 




SynchroProcess.h
C/C++ code

//#include "SynchroProcess.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifndef SYNCHRO_PROCESS
#define SYNCHRO_PROCESS

void TELL_WAIT(void);                    //提示有个等待
void TELL_PARENT(pid_t pid);            //告诉父亲等待
void TELL_CHILD(pid_t pid);            //告诉孩子等待
void WAIT_PARENT( void );                //发信息解除父亲等待
void WAIT_CHILD( void )