在计算机操作系统中,信号量机制的那两个操作是什么意思?用自己的理解回答,呵呵,我看书有点看不懂!谢谢啦!
第1个回答 2013-07-24
规定在拿到左侧的筷子后,先检查右面的筷子是否可用。如果不可用,则先放下左侧筷子, 等一段时间再重复整个过程。 分析:当出现以下情形,在某一个瞬间,所有的哲学家都同时启动这个算法,拿起左侧的筷 子,而看到右侧筷子不可用,又都放下左侧筷子,等一会儿,又同时拿起左侧筷子……如此 这样永远重复下去。对于这种情况,所有的程序都在运行,但却无法取得进展,即出现饥饿, 所有的哲学家都吃不上饭。 (2) 描述一种没有人饿死(永远拿不到筷子)算法。 考虑了四种实现的方式(A、B、C、D): A.原理:至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释 放出他所使用过的两支筷子,从而可使更多的哲学家进餐。以下将room 作为,只允 许4 个哲学家同时进入餐厅就餐,这样就能保证至少有一个哲学家可以就餐,而申请进入 餐厅的哲学家进入room 的等待队列,根据FIFO 的原则,总会进入到餐厅就餐,因此不会 出现饿死和的现象。 伪码: semaphore chopstick[5]=; semaphore room=4; void philosopher(int i) } B.原理:仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐。 方法1:利用AND 型信号量机制实现:根据课程讲述,在一个中,将一段代码同时需 要的多个临界资源,要么全部分配给它,要么一个都不分配,因此不会出现死锁的情形。当 某些资源不够时阻塞调用进程;由于等待队列的存在,使得对资源的请求满足FIFO 的要求, 因此不会出现饥饿的情形。 伪码: semaphore chopstick[5]=; void philosopher(int I) } 方法2:利用信号量的保护机制实现。通过信号量mutex对eat()之前的取左侧和右侧筷 子的操作进行保护,使之成为一个原子操作,这样可以防止死锁的出现。 伪码: semaphore mutex = 1 ; semaphore chopstick[5]=; void philosopher(int I) }
第2个回答 2019-03-08
wait(s)就是s减1
如果原来是0
那么就是wait(0)
还记得C语言中的while吗while(0)就是不进入循环一直等到while(1)再进入循环
(可以这么理解,但实际while直接不执行循环里的语句,跳过去了)
如果原来>0
直接减1,s的资源少了一个
如果原来<0
那么跟0一样还要等,等到大于0,继续执行。
signal(s)就是s加1
原理同上。
如果原来是0
那么就是wait(0)
还记得C语言中的while吗while(0)就是不进入循环一直等到while(1)再进入循环
(可以这么理解,但实际while直接不执行循环里的语句,跳过去了)
如果原来>0
直接减1,s的资源少了一个
如果原来<0
那么跟0一样还要等,等到大于0,继续执行。
signal(s)就是s加1
原理同上。
第3个回答 2019-03-06
wait操作:
sem_wait是一个函数,也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,将信号量的值将减到1。
如果对一个值为0的信号量调用sem_wait(),这个函数就会原地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值。
那么当它被第三个线程增加
一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。sem_trywait(sem_t
*sem)是函数sem_wait的非阻塞版,它直接将信号量sem减1,同时返回错误代码。
signal操作:
sig是传递给signal的唯一参数。执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。
signal()会依参数signum
指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。
当一个信号的信号处理函数执行时,如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,直到信号处理函数执行完毕再重新调用相应的处理函数。但是如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。
扩展资料:
signal操作的注意点:
1、不要使用低级的或者STDIO.H的IO函数
2、不要使用对操作
3、不要进行系统调用
4、不是浮点信号的时候不要用longjmp
5、signal函数是由ISO
C定义的。因为ISO
C不涉及多进程,进程组以及终端I/O等,所以他对信号的定义非常含糊,以至于对UNIX系统而言几乎毫无用处。
参考资料来源:百度百科-signal
参考资料来源:百度百科-sem_wait
sem_wait是一个函数,也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,将信号量的值将减到1。
如果对一个值为0的信号量调用sem_wait(),这个函数就会原地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值。
那么当它被第三个线程增加
一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。sem_trywait(sem_t
*sem)是函数sem_wait的非阻塞版,它直接将信号量sem减1,同时返回错误代码。
signal操作:
sig是传递给signal的唯一参数。执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。
signal()会依参数signum
指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。
当一个信号的信号处理函数执行时,如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,直到信号处理函数执行完毕再重新调用相应的处理函数。但是如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。
扩展资料:
signal操作的注意点:
1、不要使用低级的或者STDIO.H的IO函数
2、不要使用对操作
3、不要进行系统调用
4、不是浮点信号的时候不要用longjmp
5、signal函数是由ISO
C定义的。因为ISO
C不涉及多进程,进程组以及终端I/O等,所以他对信号的定义非常含糊,以至于对UNIX系统而言几乎毫无用处。
参考资料来源:百度百科-signal
参考资料来源:百度百科-sem_wait