其他分享
首页 > 其他分享> > IPC_信号量(学习笔记)供参考

IPC_信号量(学习笔记)供参考

作者:互联网

IPC_信号量

问题的引入

例子:
important_i = 5
func()
{
    important_i++;
} 

有两个实例任务,调用了func()这个函数,那么请问,important_i最后的值是什么?
7 -> 有可能
8 -> 有可能,不是我们期望的结果
这种情况就不是有序访问,是有问题的,所以我们需要对这个共享资源进行某种方式的保护,以使它被有序的访问。---------避免竞争


信号量机制

  • 信号量是个什么东西??
  • 信号量的作用是什么?
  • 为什么需要信号量??
  • 信号量是怎么样达到目的的??

如何来保护呢?


信号量是如何实现的呢?

创建(create)

等待(wait)

 while(semaphor_value <= 0)
    {
        sleep;//wait
    }
    semaphor_value--;    
    //表示该进程或线程,获取了该信号量
    //上述必须必须上“原子操作”:不允许有两个及以上的进程同时进入。
    //.....以下代码,获取了该信号量,就可以访问该信号量所保护的资源啦。

释放(+1)

     semaphore_value++;  //原子操作
     V操作:verhogen(增加),荷兰语
     up
     unlock 解锁

信号量保护的目标是通过:在临界区的前面加上一个 P操作 ,在临界区的会面加上一个 V操作。来实现


死锁


linux提供的信号量API

system V 信号量
Posix 信号量

system V信号量过程:ftok-------->生存一个System V ipc对象的key-----semget----->创建或者打开一个System V信号量--------- >P/V操作-------->删除该信号量

API函数接口

ftok 用来创建一个System V IPC对象 的 key

key: 最主要的特征是什么?
唯一性。

在这里插入图片描述

在这里插入图片描述


semget 用来创建或打开一个System V信号量


semctl 控制操作(设置或获取信号量集中某个或某些信号量的值)

semop : System V 信号量的P/V操作

struct sembuf
{
	unsigned short     sem_num;  
        //要进行P/V操作的信号量在信号量集中的编号(下标)
				
	short   sem_op;   /* semaphore operation */
        >0 :  => V操作, up/unlock
        =0 :  try 一  try, 看是否会阻塞
        <0 :  => P操作, down/lock
					
        semval(信号量的值) = 原semval + sem_op
				
	short    sem_flg;  /* operation flags */
        // 0 : 默认,如果 P操作获取不了,则会阻塞
        PC_NOWAIT: 非阻塞,不等待
        如果是P操作,能获取则获取,不能获取则走人(返回-1,)		
        SEM_UNDO: 撤销!!!!!!
        为了防止进程带锁退出
        if you set SEM_UNDO这个标志,
        内核会额外记录该进程对该信号量的所有的p/v操作,
        然后再该进程退出时,会还原对该信号的操作。
			如:
	     p  v  p  v   kill
	     -1 +1 -1 +1 0
										
	     p  v  p  kill
       -1 +1 -1 (-1)  还原 +1
	};
		

struct sembuf表示的对一个信号量的P/V操作
如果对两个信号量的P/V操作,就需要对应两个struct sembuf
如果对多个信号量的P/V操作,就需要对应多个struct sembuf


struct timespec
{
    long tv_sec;//秒
    long tv_nsec;//纳秒
};
//假设你要等待 2秒钟 零 200纳秒
				
struct timespec tv;
tv.tv_sec = 2;
tv.tv_nsec = 200;
				

关键:

1、明确共享资源

2、明确临界区

3、临界区前P操作,临界区后V操作


Posix信号量

单个信号量

无名信号量

有名信号量

创建或打开一个POSIX信号量

Link with -pthread. -l pthread

POSIX信号量 P/V操作

P操作

Link with -pthread

例子:
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME , &ts);  //获取当前时间
    ts.tv_sec +=5;
    ts.tv_nsec +=3000000000;
    {
        ts.tv_sec++;
        ts.tv_nsec-=1000000000;
    }
    
    int r = sem_timedwait(sem,&ts);

V操作

其他操作

sem_getvalue用来获取一个POSIX信号量的值


POSIX有名信号量的 关闭和删除 操作

POSIX无名信号量的 销毁操作

标签:IPC,int,信号量,访问,进程,供参考,sem,共享资源
来源: https://blog.csdn.net/weixin_46992369/article/details/122869061