touch ***
sudo apt update
sudo apt install gcc
gcc -o fruit fruit.c -lpthread
sudo apt update
sudo apt install libgtk-3-dev
gcc -o lru_simulator lru_simulator.c `pkg-config --cflags --libs gtk+-3.0`
7
0 7
1 0 7
2 1 0
0 2 1 (7)
如果你想完成PV除了书上的那个例子的另一个例子:
1.在Linux下创建一个名为pv的工程目录。
2.创建一个sem_pv.c的文件,写入以下代码。
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdarg.h>
#include <time.h>
#define SEM_P -1
#define SEM_V 1
#if !(defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED))
//如果系统中没有定义这个联合体,则需要额外定义一下
union semun {
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
#endif
//获取时间戳
int get_timestamp(char *timestamp)
{
time_t timep;
struct tm *p, pp;
time(&timep);
localtime_r(&timep, &pp);
p = &pp;
return sprintf(timestamp, "%04d-%02d-%02d %02d:%02d:%02d", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
}
/*
日志打印
*/
void LOG(const char *format,...)
{
va_list argptr;
char buffer[2048];
va_start(argptr,format);
vsprintf(buffer,format,argptr);
va_end(argptr);
char timestamp[64]="";
get_timestamp(timestamp);
printf("[%s][%d]%s", timestamp, getpid(), buffer);
}
int sem_init(int semid)
{
int ret;
union semun semun;
semun.val = 0;
ret = semctl(semid, 0, SETVAL, semun);
if (ret == -1) {
LOG("semctl failed!\n");
}
return ret;
}
int semop_pv(int semid, int opt)
{
int ret;
struct sembuf sembuf;
sembuf.sem_op = opt;
sembuf.sem_num = 0;//初始化为0,表示暂时没资源
sembuf.sem_flg = SEM_UNDO;
ret = semop(semid, &sembuf, 1);
if (ret == -1) {
LOG("sem_p failed!\n");
}
return ret;
}
/*
模拟P操作
*/
int semop_p(int semid)
{
//p操作 对信号量进行减1
LOG("semctl P\n");
return semop_pv(semid, SEM_P);
}
/*
模拟V操作
*/
int semop_v(int semid)
{
//v操作 对信号量进行加1
LOG("semctl V\n");
return semop_pv(semid, SEM_V);
}
/*
删除信号量
*/
void sem_del(int semid)
{
union semun sem_un;
if(semctl(semid, 0, IPC_RMID, sem_un)<0) {
LOG("sem_del fail\n");
}
}
3.创建一个名为“main.c”的文件,写入以下代码:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <time.h>
#define TEST_FILE "./test"
int file_write()
{
char timestamp[64]="";
FILE *fp = fopen(TEST_FILE, "ab+");
if(!fp) {
LOG("[%s](%d)open %s failed!\n", __func__, __LINE__, TEST_FILE);
return -1;
}
get_timestamp(timestamp);
//将进程号写入文件
fprintf(fp, "[%s]Process (%d)write!!!\n", timestamp, getpid());
fclose(fp);
return 0;
}
int main(int argc, char* argv[])
{
int i;
int ret;
int semid;
int timeout = 5;//测试写文件操作5次
int sleep_second = 1;
/* 获取信号量 键值设置为6666,
1表示信号量的数量,
后面表示如果没有这个信号量就创建而且设置为都可以访问的权限*/
semid = semget((key_t)6666, 1, 0666 | IPC_CREAT);
/*如果没有创建成功就会返回-1 然后打印失败的信息*/
LOG("semid=%d\n", semid);
if (semid == -1) {
LOG("semget failed!\n");
exit(1);
}
/* 初始化信号量 */
ret = sem_init(semid);
if (ret == -1) {
exit(1);
}
if(argc<2) {
LOG("Input error!!!\n");
exit(0);
}
int param = atoi(argv[1]);
if(param==1) {
//参数为1的进程进行V操作
if (semop_v(semid) == -1) {
exit(1);
}
sleep(1);
}
else {
unlink(TEST_FILE);
}
while(timeout--) {
//刚开始
if (semop_p(semid) == -1) {
exit(1);
}
/* 临界区操作*/
LOG("begin write\n");
file_write();
sleep(sleep_second);
LOG("write done!\n");
if (semop_v(semid) == -1) {
exit(1);
}
}
/* 删除信号量 */
if(param==1) {
sem_del(semid);
}
return 0;
}
4.创建一个Makefile文件,写入以下内容:
CPROG = pv
BIN = $(CPROG)
CC= gcc
OBJS=main.o sem_pv.o
all: $(BIN)
clean:
rm -f $(OBJS) $(BIN)
$(BIN): $(OBJS)
$(CC) -o $(BIN) $(OBJS) $(CFLAGS) $(LDFLAGS) $(CFLAGS_EXTRA)
5.在当前目录下执行make clean;make编译生成一个pv_test可执行文件
6.测试。运行时,使用参数0和1来区分不同的进程。
味曾名郎
- 粉丝: 0
- 资源: 1
最新资源
- vlmcsd-1113-2020-03-28-Hotbird64(最新版本KMS)
- 433.基于SpringBoot的冷链物流系统(含报告).zip
- com.harmonyos4.exception.PowerFailureException(怎么解决).md
- 使用 Python 字典统计字符串中每个字符的出现次数.docx
- com.harmonyos4.exception.SystemBootFailureException(怎么解决).md
- 球队获胜数据集.zip
- ERR-NULL-POINTER(解决方案).md
- <项目代码>YOLOv8 航拍行人识别<目标检测>
- 计算机网络-socket-inet-master.zip
- Java编程学习路线:从基础到实战全攻略
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈