首页 理论教育 嵌入式Linux编程实例与信号量的作用

嵌入式Linux编程实例与信号量的作用

时间:2023-10-31 理论教育 版权反馈
【摘要】:1965年,E.W.Dijkstra提出了信号量的概念。之后,信号量成为操作系统实现互斥和同步的一种普遍机制。此时信号量集的semid_ds结构的sem_base.semval将加上sem_op的值。如果设置了IPC_NOWAIT位,则函数出错返回,否则semid_ds结构的sem_base.semncnt加1,进程等待至sem_base.semval大于sem_op的绝对值或该信号量被删除。

嵌入式Linux编程实例与信号量的作用

1965年,E.W.Dijkstra提出了信号量的概念。之后,信号量成为操作系统实现互斥和同步的一种普遍机制。信号量是一种特殊的变量,只能取正整数值,对这些正整数只能采取两种操作:P操作(代表等待、关操作)、V操作(代表信号、开操作)。定义如下:

●P(sem):如果sem的值大于0,则sem减1;如果sem的值为0,则挂起该线程

●V(sem):如果有其他进程因等待sem而被挂起,则让它恢复执行;如果没有线程等待sem而被挂起,则sem加1。

1.创建信号量

在使用信号量之前,首先需要创建一个信号量。创建一个信号量的函数为semget(),其函数声明如下:

该函数用来打开一个新的信号量集合,或者打开一个已经存在的信号量集合。其中,参数key表示所创建或打开的信号量集的键;参数nsems表示创建的信号量集中信号量的个数,此参数只在创建一个新的信号量集时才有效;参数flag表示调用函数的操作类型,也可以用来设置信号量集的访问权限。调用函数semget()的作用由参数key和flag决定。函数调用成功时,返回值为信号量的引用标识符,调用失败时,返回值为-1。

2.对信号量的操作

对信号量的操作使用如下函数:

参数semid是信号量集的引用id,semoparray[]是一个sembuf类型的数组,sembuf结构用于指定调用semop()函数所做的操作,数组semoparray[]中的元素的个数由nops决定。Sembuf的结构如下:

其中,sem_num指定要操作的信号量;sem_flag为操作标记;sem_op用于表示所执行的操作。相应取值的含义如下:(www.xing528.com)

sem_op>0:表示线程对资源使用完毕,交回该资源。此时信号量集的semid_ds结构的sem_base.semval将加上sem_op的值。如果此时设置了SEM_UNDO位,则信号量的调整值将减去sem_op绝对值。

sem_op=0:表示进程要等待,直到sem_base.semval的值变为0。

sem_op<0:表示进程希望使用资源。此时将比较sem_base.semval和sem_op的绝对值的大小。如果sem_base.semval大于sem_op的绝对值,则表示资源足够分配给该进程,sem_base.semval将减去sem_op的绝对值。此时如果设置了SEM_UNDO位,则信号量的调整值将加上sem_op的绝对值。如果sem_base.semval小于sem_op的绝对值,则表示资源不足。如果设置了IPC_NOWAIT位,则函数出错返回,否则semid_ds结构的sem_base.semncnt加1,进程等待至sem_base.semval大于sem_op的绝对值或该信号量被删除。

3.对信号量的控制

对信号量的控制操作是通过semctl()来实现的。该函数的原型如下:

其中,参数semid为信号量集的引用标识符;参数semnum用于指定信号量集中某个特定的信号量;参数cmd表示调用该函数希望执行的操作;参数arg是senum联合。

参数cmd的最常用的两个值是SETVAL和IFC_RMID。SETVAL用来把信号量初始化为一个已知的值,这个值在senum结构里是以val成员的面貌传递的,作用是在信号量第一次使用之前对其进行设置;IFC_RMID的作用是删除一个已经没人使用的信号量标识码。

semctl()会根据cmd参数返回几个不同的值。对于SETVAL和IFC_RMID,成功时返回0,失败时返回-1。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈