欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

一起talk C栗子吧(第一百零二回:C语言实例--使用信号量进行进程间同步与互斥三)

程序员文章站 2022-09-28 16:37:49
各位看官们,大家好,上一回中咱们说的是使用信号量进行进程间同步与互斥的例子,这一回咱们继续说该例子。闲话休提,言归正转。让我们一起talk C栗子吧! 看官们,我们在上一...


各位看官们,大家好,上一回中咱们说的是使用信号量进行进程间同步与互斥的例子,这一回咱们继续说该例子。闲话休提,言归正转。让我们一起talk C栗子吧!

看官们,我们在上一回中介绍了信号量相关的函数及其用法,这一回中我们通过具体的例子来说明如使用这些函数来操作信号量。

下面是具体的使用步骤

1.使用semget函数创建一个信号量; 2.使用semctl函数初始化信号量; 3.使用semop函数对信号量进行P操作,以便进程进入临界区操作临界资源; 4.使用semop函数对信号量进行V操作,以便进程离开临界区时唤醒其它进程; 5..使用semctl函数删除信号量;

大家还记得我们在前面章回中的伪代码吧,我们将把这些伪代码转换为实际的C语言代码:

nocritical code   //非临界区的代码
P(sem);           //执行P操作,进入临界区,执行临界区中的代码
{
    critical code; //临界区代码
    do something
}
V(sem);           //执行V操作,离开临界区
nocritical code   //非临界区的代码

看官们,正文中就不写代码了,详细的代码放到了我的资源中,大家可以下载使用。

另外,我说一下代码中的内容(可以下载代码后对比着看):代码开始处自己定义了联合体semun,不然会有编译错误,详细如下:

union semun
 {
    int              val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INFO */
 };

代码中对信号量的操作都进行了封装,比如把semctl函数封装成了初始化和删除信号量的函数,把semop函数封装成了信号量的P/V操作。此外,我们在代码中对使用参数和不使用参数这两种情况进行了区分,而且在使用参数时对程序进行了延时操作,这样是为了方便大家观察程序运行结果。

下面是程序的运行结果,请大家参考:
(在运行程序时使用-s参数表示对信号量进行初始化和删除操作,不使用参数时只进行P/V操作。)

$./a -s &                            //在后台运行编译后的程序a,参数-s表示初始化或者删除信号量
[1] 2713                             //程序在后台运行,这里启动了后台进程,PID:2713
$ [pid: 2713 ] init semaphore  
[pid: 2713 ] running nocritical code 
$./a                                 //在前台运行程序,不使用任何参数,这里启动了前台进程,PID:2714
[pid: 2714 ] running nocritical code 
[pid: 2713 ] enter critical area 
[pid: 2713 ] running critical code   //后台进程执行临界区的代码
[pid: 2713 ] leave critical area 
[pid: 2714 ] enter critical area
[pid: 2714 ] running critical code   //前台进程执行临界区的代码
[pid: 2714 ] leave critical area 
[pid: 2714 ] running nocritical code 
$ [pid: 2713 ] delete semaphore  
[pid: 2713 ] running nocritical code 
                                       //需要按下回车键切换到终端窗口中
[1]+  Done                    ./a -s   //后台进程运行结束

大家从上面的运行结果中可以看到,首先是后台进程执行临界区中的代码,然后才是前台进程执行临界区中的代码。也就是说同一段时间内只能有一个进程操作临界区的代码,这便是进程之间的同步与互斥。

各位看官,关于使用信号量进行进程间同步与互斥的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。