Linux 内核同步方法(锁机制)(1)

**

1.自旋锁:

:**Linux中最常见的锁,在短时间内进行清亮级加锁。如果一个执行线程试图获取一个已经被持有的自旋锁,那么该线程就会一直进行忙循环——旋转——等待锁重新可用。
注意:自旋锁在Linux不可递归(当试图获取一个自己已经持有的锁时,本身在自旋等待自己释放锁,这时候自己将永远无法释放锁,会造成死锁的情况。)

1.2读写自旋锁:

用途明确分为读取和写入(内核中任务链表的保护就是由读写自旋锁实现的)一个或多个读任务可以并发的持有读锁,但是写锁只能最多被一个写任务持有,且不能有并发的读操作。
注意:当将一个读锁升级为写锁时,会造成死锁。写锁只能在读锁完全被释放的情况下才能被获得。

以上两种锁适用于加锁的时间比较短,且代码不会睡眠(中断处理程序)。

1.3信号量:

Linux中的信号量是一种睡眠锁,当一个任务试图获得一个被占用的信号量时,它会被推进一个等待对列,然后让其睡眠。当这个信号量被释放时,等待队列中的一个任务被唤醒,且持有此信号量。
一个信号量可以被多个任务所持有,但是通常情况下在一个时刻只允许一个锁的持有者,这时计数器等于1,也称为二值信号量因为只有0个或者1个持有锁。当初始化信号量时将可持有者数设置为大于1个时,这时信号量被称为计数信号量。下面是用信号量写的一个生产者消费者模型
int main(void)
{
int*addr=mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0);
if(addr==MAP_FAILED)
{
perror(“mmap”);
exit(-1);
}
//信号量
int semid=semget(ftok(“.”,100),2,IPC_CREAT|0666);
semctl(semid,0,SETVAL,0); //0号信号量用来读
semctl(semid,1,SETVAL,1); //1号信号量用来写

struct sembuf sem_r_v={0,1,0}; //释放
struct sembuf sem_r_p={0,-1,0};//获取

struct sembuf sem_w_v={1,1,0}; //释放
struct sembuf sem_w_p={1,-1,0};//获取
if(fork()>0)//生产者
{
    int i=0;
    while(i<100)
    {
    semop(semid,&sem_w_p,1);//获取写锁
    //生产
    *addr=i++;
    printf("产品已生产,%d\n",*addr);
    sleep(1);
    semop(semid,&sem_r_v,1);//释放读锁  
    }
}
else
{
    while(1)
    {
    semop(semid,&sem_r_p,1); //获取读锁
    //消费
    printf("产品已消费,%d\n",*addr);
    sleep(1);
    semop(semid,&sem_w_v,1);//释放写锁
    }
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值