Linux IPCs - Semaphore

                                                         Linux IPCs - Semaphore

 

     Semphore 是linux提供的一种进程间通信机制,可以用于共享资源的互斥以及进程间同步。

 

1. 资源互斥

     互斥的目的是保证资源访问的排它性,和 Mutex 的主要区别如下:

    1)Mutex 用于保护具有唯一性的资源,禁止并发访问,多用于Critical section 的保护;

       而Semaphore用于保护具有多份的共享资源,限制对同一资源并发访问的数量

     2)Mutex 的使用一定遵循谁加锁谁释放的原则,不可以用于进程之间;

       而Semaphore 则可以由不同的人来加锁、释放,可以用于进程之间

2. 进程同步

     Semaphore 多用于进程之间的同步,协调进程的执行顺序,Linux 包含Posix、System V两种Semaphore。Posix Semaphore 分为有名和无名,无名Semaphore只可以用于进程之内。

3. P\V原语

    主要包含P、V原语操作,p操作和v操作是不可中断的程序段,称为原语。P,V原语中P是荷兰语的Passeren,相当于英文的pass,V是荷兰语的Verhoog,相当于英文中的incremnet。
P原语操作的动作是:
(1)S减1;
(2)若S减1后仍大于或等于零,则进程继续执行;
(3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
V原语操作的动作是:
(1)S加1;
(2)若相加结果大于零,则进程继续执行;
(3)若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。

每一个信号量都会维护一个wait_list

struct semaphore {
    raw_spinlock_t      lock;
    unsigned int        count;
    struct list_head    wait_list;
};

P操作,当线程因等待该信号量挂起时,便会插入到这个wait_list的尾部

    list_add_tail(&waiter.list, &sem->wait_list);
    waiter.task = task;
    waiter.up = false;

V操作,如果计数值大于0则将list中的第一个进程取出插入到执行队列里面,等待CPU调度

static noinline void __sched __up(struct semaphore *sem)
{
    struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
                        struct semaphore_waiter, list);
    list_del(&waiter->list);
    waiter->up = true;
    wake_up_process(waiter->task);
}

/**
 * try_to_wake_up - wake up a thread
 * @p: the thread to be awakened
 * @state: the mask of task states that can be woken
 * @wake_flags: wake modifier flags (WF_*)
 *
 * Put it on the run-queue if it's not already there. The "current"
 * thread is always on the run-queue (except when the actual
 * re-schedule is in progress), and as such you're allowed to do
 * the simpler "current->state = TASK_RUNNING" to mark yourself
 * runnable without the overhead of this.
 *
 * Return: %true if @p was woken up, %false if it was already running.
 * or @state didn't match @p's state.
 */

也就是说,V操作时被唤醒的进程并不会马上执行,而是要等待下一次CPU调度时,按照优先级调度。并且进程唤醒的是按照阻塞的先后顺序(在wait_list中的顺序)
在使用中测试发现V操作非常的耗时,主要时间应该消耗在线程唤醒上面了
 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值