为了练习信号量我写了一些基本的代码来理解这个概念
服务器代码如下
#include "MySem.h"
#include "MyShm.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/types.h>
void signalHandler(int signum);
int shmid = 0;
int *shmaddr = 0;
int semidServ = 0;
int semidClnt = 0;
int main(int argc, char const *argv[]) {
int req = 0;
int res = 0;
union semun semunBuf;
shmid = createShm(MY_SHM_KEY);
shmaddr = shmat(shmid, NULL, 0);
semidServ = creatSem(MY_SEM_SERV_KEY);
semunBuf.val = 0;
semctl(semidServ, 0, SETVAL, semunBuf);
semidClnt = creatSem(MY_SEM_CLNT_KEY);
semunBuf.val = 1;
semctl(semidClnt, 0, SETVAL, semunBuf);
signal(SIGINT, signalHandler);
while (1) {
puts("Wait ...");
lockSem(semidServ);
memcpy(&req, shmaddr, sizeof(int));
res = req + 1;
memcpy(shmaddr, &res, sizeof(int));
unlockSem(semidClnt);
printf("Request: %d\n", req);
printf("Response: %d\n", res);
fflush(stdout);
}
return 0;
}
客户端代码是这样的
#include "MySem.h"
#include "MyShm.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/types.h>
void signalHandler(int signum);
int shmid = 0;
int *shmaddr = NULL;
int semidServ = 0;
int semidClnt = 0;
int main(int argc, char const *argv[]) {
int req = 0;
int res;
shmid = openShm(MY_SHM_KEY);
shmaddr = shmat(shmid, NULL, 0);
semidServ = openSem(MY_SEM_SERV_KEY);
semidClnt = openSem(MY_SEM_CLNT_KEY);
signal(SIGINT, signalHandler);
while (1) {
printf("<<");
scanf("%d", &req);
fflush(stdout);
fflush(stdin);
lockSem(semidClnt);
memcpy(shmaddr, &req, sizeof(int));
unlockSem(semidServ);
lockSem(semidClnt);
memcpy(&res, shmaddr, sizeof(int));
unlockSem(semidClnt);
printf(">> %d\n", res);
}
return 0;
}
我想知道的是,在scanf函数之后的客户端代码中,两个信号量都被lockSem(semidClnt)锁定为值0;服务器和客户端之间的通信仍然有效吗?我对这段代码有什么误解吗?
1条答案
按热度按时间c8ib6hqw1#
我不清楚你在问什么。我认为你只是想让我们重新检查代码。
这很好,但我会简化客户端。
首先,信号量不能被锁定。您可以使用信号量作为互斥量,但您没有这样做。因此,在这里将信号量称为被锁定是没有意义的。
在我的简化版本中,我还将使用两个信号量。
request_sem
,它有两种状态:| 状态|意义|初始|
| - -----|- -----|- -----|
| 0|没有待处理的请求。|初始状态。|
| 1|请求待定。||
request_sem
是semidServ
的新名称。response_sem
,它有两种状态:| 状态|意义|初始|
| - -----|- -----|- -----|
| 0|没有答复。|初始状态。|
| 1|响应准备就绪。||
response_sem
替换了semidClnt
。它与原始程序中的semidClnt
具有完全不同的状态,并且具有不同的初始状态。描述semidClnt
的状态非常复杂,这是一个可以改进的明确指标。服务器代码保持不变(除了名称)。
简化了客户端代码。
我们可以很容易地验证我们的假设(“X被期望为Y”),并看到这段代码工作正常,同时简单得多。