一、实验目的
1. 加深理解线程同步的概念及实现线程同步的原理。
2. 掌握Linux线程库支持的信号量同步机制和信号量互斥机制,学会通过信号量信号实现线程间的同步与互斥。
二、实验内容
实验七、线程同步实现公交车司机与售票员同步,
参考实验四,完成该程序的设计
三、原理和实验主要步骤
1、原理:Linux的线程库中定义了同步信号量以及多种同步信号量操作函数(原语)。
POSIX信号量同步信号量的类型为sem_t
基本的同步信号量操作函数有4个:
sem_init( )
sem_wait( )
(相当于P操作)
sem_post( )
(相当于V操作)
sem_destroy( )
它们均在头文件semaphore.h中声明。
sem_init
函数
原型:int sem_init(sem_t *sem, int type, int value);
其中,参数sem为同步信号量的指针;type为信号量类型,若为0,表示该信号量是现行进程的局部信号量(只在现行进程的线程之间使用),否则,它可为多个进程所共享;value是信号量值的初值。
功能:初始化同步信号量。
sem_wait
函数
原型:int sem_wait(sem_t *sem);
功能:同步信号量的P操作
sem_post
函数
原型:int sem_post(sem_t *sem);
功能:同步信号量的V操作
sem_destroy
函数
原型:int sem_destroy(sem_t *sem);
功能:清理同步信号量
上述函数返回0表示成功,非0表示失败。
2、本实验要求应用Linux线程库支持的信号量互斥机制改进实验4.2,即程序test4_2.c 。
该互斥机制的内容见讲义Unit 4中的4.2节。
本实验的程序框架和部分程序代码如下,请完成该程序的设计,
/*test6_1.c*/
#include<stdio.h>
#include<pthread.h>
int ticket[10]={1,3,5,7,9,2,4,6,8,10};
int rest=10;
int th_num[2]={1,2}; /*自定义的线程序号*/
<定义一个互斥信号量>
void *terminal(void *p) /*售票终端线程代码*/
{ int mynum=*((int *)p); /*本终端的序号*/
int tot=0; /*本终端售票计数*/
<你的设计部分>
printf(“Terminal_%d selled %d tickets .\n”, mynum,tot);
pthread_exit(0);
}
int main( )
{
pthread_t tid[2];
<初始化信号量>
pthread_create(&tid[0], NULL, terminal, &th_num[0]);
/*参数“&th_num[0]”是线程的入口参数*/
pthread_create(&tid[1], NULL, terminal, &th_num[1]);
<等待线程终止>
<撤消信号量>
<结束>
}
问题描述:
公共汽车上,司机和售票员的活动分别是:
司机的活动:启动车辆;正常行车;到站停车。
售票员的活动:关车门;售票;开车门。
在汽车不断的到站、停站、行驶过程中,用信号量和P,V操作实现它们的同步。
- 实验结果测试
1.对于test6_1的修改,代码如图1-图2所示。其中,使用pthread_mutex_t
定义了互斥信号量,使用pthread_mutex_lock
对应互斥信号量的P操作,使用pthread_mutex_unlock
对应互斥信号量的V操作。


2.完成编辑后,使用gcc命令编译文件,运行生成的文件,结果如图3所示。

思考:◆Linux系统中,信号量值和P、V是怎么样对应的?
答:信号量的值和P、V操作是通过以下方式相互对应的:
信号量的值:每个信号量都有一个整数值,通常表示可用资源的数量或者某种状态。值可以是任意整数。
P操作用于请求获取一个资源。在Linux中,通过调用semop()系统调用实现P操作。当进程执行P操作时,它将尝试将信号量的值减1。如果信号量的值大于0,则成功获取到资源,并将信号量的值减1;如果信号量的值为0,则进程将被阻塞,直到信号量的值变为非零。
V操作用于释放一个资源。在Linux中,通过调用semop()系统调用实现V操作。当进程执行V操作时,它将尝试将信号量的值加1。如果有其他进程因为等待该资源而被阻塞,则其中一个进程将被唤醒并获得该资源;如果没有进程在等待该资源,则信号量的值增加1。
通过对信号量的值进行P和V操作,可以实现多个进程之间的互斥和同步,以确保对共享资源的正确访问和使用。