linux 自旋锁!

发布于 2022-09-18 19:05:37 字数 7742 浏览 17 评论 0

我写一个简单的驱动程序!
要验证一下自旋锁的功能!在没有释放锁的情况下,理说其它的线程应该是获取不到这个锁的!
可是为什么,下面这个程序却能执行关闭文件?(在下面修改后的程序里面.故意打开文件的时候,获取了锁,而不放.应该在关闭的时候应该是进程给挂起了!可是程序还是执行下去了,而且完成了相同的操作)
前辈给于指教!!谢谢!
驱动码:

spinlock_t lock=SPIN_LOCK_UNLOCKED;
static int file_count;
static int signel_open(struct inode *inode,struct file *file )
{ printk("get lock\n");
  spin_lock(lock);
  if(file_count)
      { spin_unlock(lock);
      return -EBUSY;
          }
  file_count++;
  spin_unlock(lock);
  return 0;
 
      }
static int signel_close(struct inode *inode,struct file *file)
{ file_count--;
  return 0;
     }

以下是修改后的,没有加入spin_unlock();
static int signel_open(struct inode *inode,struct file *file )
{ printk("get lock\n");
  spin_lock(lock);
  file_count++;
  return 0;
     }
static int signel_close(struct inode *inode,struct file *file)
{
   file_count--;
   return 0;
     }

#define DEV_NAME "/dev/signel"
int main()
{ int fd,ret;
  int a=01;
  fd=open(DEV_NAME,O_RDWR);
  if(fd<0)
      { printf("opened is fail!!\n");
         }
   else
       { printf("open is scuss!!!\n");
      printf("writr a=%d\n",a);
      write(fd,&a,sizeof(a));
    }
   close(fd);
   printf("closed the file!!\n");
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

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

评论(9

臻嫒无言 2022-09-25 19:05:37

关闭文件的时候,哪里有请求自旋锁?

Saygoodbye 2022-09-25 19:05:37

落了!!
static int signel_close(struct inode *inode,struct file *file)
{ spin_lock(lock);
   file_count--;
   return 0;
     }
lock应该是个地址!&lock!没有写上!   close进程就不挂起!

[ 本帖最后由 shuiyu123 于 2009-3-15 18:03 编辑 ]

信仰 2022-09-25 19:05:37

那这就对了,呵呵

夜吻♂芭芘 2022-09-25 19:05:37

为什么close进程挂不起来?
dreamice !!!!

生生漫 2022-09-25 19:05:37

spin_lock(&lock);
而且没有看到你的设备初始化

逆光飞翔i 2022-09-25 19:05:37

我把代码全都贴出来! 先不看,不管write与read这两个是关于信号量,就看open close!程序就这些不知道是哪里出了问题
!把OPEN,CLOSE改成这样:
static int signel_open(struct inode *inode,struct file *file )
{ printk("get lock\n");
  spin_lock(&s_lock);     这里取锁,我不放掉!看到close里面能不能把进程给挂起!
  f_count++;
  return 0;
}
static int signel_close(struct inode *inode,struct file *file)
{ spin_lock(&s_lock);   在这里进程应该挂起才对!!
  f_count--;
  return 0;
     }
运行结果与下面的一样!
#define  DEV_NAME  "signel"
#define  DEV_ID 110
static int flags=0;
static DECLARE_WAIT_QUEUE_HEAD(in);
static int arry[4];
struct semaphore sem;
spinlock_t s_lock;  锁的声明!!!
static int f_count;
static int signel_open(struct inode *inode,struct file *file )
{ printk("get lock\n");
  spin_lock(&s_lock);
  if(f_count)
          { spin_unlock(&s_lock);
      return -EBUSY;
              }
  f_count++;
  spin_unlock(&s_lock);
  return 0;

      }
static int signel_write(struct file *file,const char __user * buf,size_t count,loff_t *off)
{ printk("%i,%s\n",current->pid,current->comm);
  flags=1;
  if(down_interruptible(&sem))
           { return -ERESTARTSYS;
              }
  printk("write data....!!!\n");
  if(copy_from_user(&arry,buf,count))
          { up(&sem);
      return -EFAULT;
             }
  wake_up_interruptible(&in);
  up(&sem);
  return count;
    }   
static int signel_read(struct file *file,char __user * buf,size_t count,loff_t *off)
{  printk ("%i,%s\n",current->pid,current->comm);
   if(wait_event_interruptible(in,flags!=0))
     { return -ERESTARTSYS;
               }
   if(down_interruptible(&sem))
    { return -ERESTARTSYS;
              }
   flags=0;
   printk("read data....!!!\n");
   if(copy_to_user(buf,&arry,count))
           { up(&sem);
      return  -EFAULT;
              }
   up(&sem);
   return count;
    }
static int signel_close(struct inode *inode,struct file *file)
{ f_count--;
  return 0;
     }
static struct file_operations signel_test = {
.write   =   signel_write,
.read    =   signel_read,
.open    =   signel_open,
.release =   signel_close,
};
static int __init init_signel(void)
{ int ret;
  sema_init(&sem,1); /* 或者用init_MUTEX(&sem) 初始化并声明为互斥(实际上也就是将信号量为“1”也就是它互斥模式)*/
  spin_lock_init(&s_lock);  锁的初始化!!!!!
  ret=register_chrdev(DEV_ID,DEV_NAME,&signel_test);
  if(ret<0)
          { printk("registre is fail!!\n");
      return ret;
        }
   else
           { printk("registre is scuss!!\n");
      devfs_mk_cdev(MKDEV(DEV_ID,0),S_IFCHR | S_IRUSR | S_IWUSR,"signel");
          return 0;
               }
   return 0;
      }
static void __exit exit_signel(void)
{ unregister_chrdev(DEV_ID,DEV_NAME);
  devfs_remove(DEV_NAME);
      }

[ 本帖最后由 shuiyu123 于 2009-3-15 21:42 编辑 ]

骑趴 2022-09-25 19:05:37

你看一下close()的返回值,如果close返回非0,那就说明调用close出了错了。

手心的海 2022-09-25 19:05:37

返回一个"0"把OPEN,CLOSE改成这样:
static int signel_open(struct inode *inode,struct file *file )
{ printk("get lock\n");
  spin_lock(&s_lock);     这里取锁,我不放掉!看到close里面能不能把进程给挂起!
  f_count++;
  return 0;
}
static int signel_close(struct inode *inode,struct file *file)
{ spin_lock(&s_lock);   在这里进程应该挂起才对!!
  f_count--;
  return 0;
     }
应该返回一个非"0"那是才是对的!
运行结果返回一个"0",这里应该是不会出现返回一个"0"值如果改成这样的话!
int main()
{ int fd,ret;
  int a=01;
  fd=open(DEV_NAME,O_RDWR);
  if(fd<0)
          { printf("opened is fail!!\n");
             }
   else
           { printf("open is scuss!!!\n");
      printf("writr a=%d\n",a);
      write(fd,&a,sizeof(a));
    }
   ret=close(fd);
     if(ret)
            { printf("the process is hanging,ret=%d\n",ret);  返回一个非"0"进程就挂起!
               }
     else
          { printf("the file is closed,ret=%d\n",ret); 返回"0"打印file关闭!
               }

百变从容 2022-09-25 19:05:37

自旋锁,本质上讲,是专门为多处理器架构设计的,当然支持抢夺式进程调度的内核在单处理器上也可以使用自旋锁。如果在一个非抢占式单处理器的系统中进入自旋,那么这个自旋将永远无法退出,因为没有其他进程可以打断当前这个自旋的进程(注意自旋简单的说,底层实现为一个无限循环)。基于这个原因,自选操作在非抢占式单处理器系统中被优化为nothing,即不执行任何操作,除非使用自旋锁时涉及到中断例程。
注意:
1. 自旋锁底层实现为一个整型,通过设计其为0或1表示锁释放或者锁定。
2. 基于以上说明,自旋锁可能被优化为不执行任何操作。
3. 你是否发现你执行锁定,再锁定都在同一个main进程中。
4. 参考LDD3第五章内容。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文