[转]虚拟机软件VMware Workstation发布16.2.0更新:添加对Win11的TPM支持
10 月 17 日消息,据 Neowin 报道,在几天前,VMWare 发布了 16.2.0 版本更新,但是黑暗模式出现了问题,VMWare 已经承认了这一点,并将很快发布修复程序。
值得一提的是,官方的更新日志并没有提到,在更新中,VMWare 还添加了对Win11软件级别 TPM 的支持。
此前,如果用户一直在启用 TPM 的 VMware Workstation Pro 中使用 Win11 虚拟机,用户必须为每个加密的 VM 设置和输入密码。但是本次更新之后,用户可以移除加密,并加入软件级 TPM 标志来代替,不必每次都要输入密码。
如果你在 Windows 中用 BitLocker 进一步加密虚拟机,可能需要在执行下面的步骤前先解密驱动器。
如果你已经在Windows 10或 11 中添加了 TPM:
确保你已经更新到 16.2.0 版本。
继续阅读 »
c++使用protobuf3,附例子
protobuf编译器是用c++写的,对于c++用户而言,除了安装protoc之外,还要安装c++运行时。
Please follow the C++ Installation Instructions to install protoc along with the C++ runtime.
或者直接根据以下步骤进行操作:
1 2 3 4 5 6 7 8 9 10 11 |
sudo apt-get install autoconf automake libtool curl make g++ unzip git clone https://github.com/protocolbuffers/protobuf.git cd protobuf git submodule update --init --recursive ./autogen.sh # To build and install the C++ Protocol Buffer runtime and the Protocol Buffer compiler (protoc) execute the following: ./configure make sudo make install sudo ldconfig # refresh shared library cache. |
oracle 利用shell脚本自动执行raman热备(全量和增量)
1、不废话直接上脚本
vim oracle_rman_bak.sh
#!/bin/sh
source /home/oracle/.bash_profile
if [ -z $1 ]
then
echo “Please Input a number,Usage: 0|1|2”
exit
else
RMAN_LEVEL=$1
fi
export ORACLE_SID=jkdata
export TODAY=date '+%Y%m%d'
export RMAN_DIR=/data/backup/oracledata/rmanbak/$ORACLE_SID/$TODAY-$RMAN_LEVEL
#######
mkdir -p $RMAN_DIR
cd $RMAN_DIR
LogFile=ora_rman_bk_$ORACLE_SID-L$RMAN_LEVEL-date '+%Y%m%d'
.log
# rman backup
rman target / msglog=$RMAN_DIR/$LogFile<<EOF
delete noprompt obsolete;
CONFIGURE BACKUP OPTIMIZATION ON;
CONFIGURE CONTROLFILE AUTOBACKUP ON;
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO ‘$RMAN_DIR/cf%F’;
run {
allocate channel c1 type disk;
allocate channel c2 type disk;
backup as compressed backupset incremental level $RMAN_LEVEL filesperset 3 tag ‘dbL$RMAN_LEVEL’ format ‘$RMAN_DIR/ora_o_%d_%t_%c%s%p%u’
database skip readonly include current controlfile;
sql ‘alter system archive log current’ ;
backup(archivelog all format ‘$RMAN_DIR/ora_a_%d_%t_%c%s%p%u’ delete input);
release channel c1;
release channel c2;
}
list backup;
exit;
EOF
#mail backup log
mail -s “$ORACLE_SID rman L$RMAN_LEVEL backup log $TODAY” [email protected] <$RMAN_DIR/$LogFile
2、在crontab 中设置如下:
0 4 * * 5 sh /home/oracle/backup_scripts/oracle_rman_bak.sh 0 > /data/backup/oracledata/logs/rman.log 2>&1
0 4 * * 2 sh /home/oracle/backup_scripts/oracle_rman_bak.sh 1 > /data/backup/oracledata/logs/rman.log 2>&1
(C语言)多进程实现消费者生产者pv操作(Windows和Linux版本)
多进程实现消费者生产者问题
一,实验目的
1,了解生产者消费者的互斥与同步问题
2,掌握Windows和Linux的进程通信方法
二,实验要求
完成Windows版本和Linux版本。
一个大小为3的缓冲区,初始为空。
2个生产者
随机等待一段时间,往缓冲区添加数据,
若缓冲区已满,等待消费者取走数据后再添加
重复6次
3个消费者
随机等待一段时间,从缓冲区读取数据
若缓冲区为空,等待生产者添加数据后再读取
重复4次
显示每次添加和读取数据的时间及缓冲区的状态
三,实验环境
Windows版本:Windows 10 64位系统,Dev-cpp编译器
Linux版本:Fedora29版本,gcc环境 vim文本编辑器
四,实验代码结构
1),pv操作伪代码:
array[3]:interger//缓冲区定义,大小为三
int empty=3,full=0;
int mutex=1;
i=0,j=0//缓冲区指针
x,y:item //产品变量
生产者: 消费者:
begin:
produce a product to x;
P(empty);
P(mutex);
array[i]=x;
ii=(i+1)%3;
V(full);
V(mutex);
,,,,,, ………,
End
消费者:
2)实验代码分析
Windows版本:
思路分析:Windows创建多进程使用creatprocess()函数调用自己,通过多次创建得到两个生产者进程三个消费者进程,在之中运行相应的生产者函数,消费者函数。在通过传入参数不同,来辨别是第一次主进程还是生产者进程,消费者进程。通过构建共享内存区进行进程间通信。
①多进程创建
② 构建共享内存区,再将文件映射到本进程,初始化
③在主创建进程间信号量full empty
分别在生产者消费者进程创建互斥访问量mutex
④同过argv量的不同判断进程归属
⑤运行结果:
全部代码见后
Linux版本:
思路分析:Linux使用fork进行多进程创建,分别在进程中运行消费者函数,生产者函数。建立共享主存区很信号量在进程建进行通信和缓存访问
②建立共享主存并进行映射
③创建进程间信号量full,empty和互斥量 mutex,并初始化
④实验结果:
五, 实验总结
本次实验获得圆满成功。
本次实验通过分别编写Windows和Linux版本的多进程实现消费者和生产者问题,了解生产者消费者的互斥与同步问题,掌握Windows和Linux的进程通信方法,也同时加强自己对多进程操作的理解。
代码:
Windows版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
//实验三生产者消费者 #include <windows.h> #include <stdio.h> #include <time.h> HANDLE handleOfProcess[5]; struct buf { char buffer[3]; int write; int read; }; int rand_1() { return rand() % 100 + 1000; } char rand_char() { return rand() % 26 + 'A'; } void StartClone(int nCloneID) { TCHAR szFilename[MAX_PATH]; GetModuleFileName(NULL, szFilename, MAX_PATH); TCHAR szCmdLine[MAX_PATH]; sprintf(szCmdLine, "\"%s\" %d", szFilename, nCloneID); //printf("%s\n",szCmdLine); STARTUPINFO si; ZeroMemory(reinterpret_cast<void*>(&si), sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi; BOOL bCreateOK = CreateProcess( szFilename, szCmdLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &si, &pi); if (bCreateOK) handleOfProcess[nCloneID] = pi.hProcess; else { printf("Error in create process!\n"); exit(0); } } void pro()//生产者 { HANDLE mutex = CreateMutex(NULL, FALSE, "MYMUTEX"); HANDLE empty = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "MYEMPTY"); HANDLE full = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "MYFULL"); HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "myfilemap"); LPVOID Data = MapViewOfFile(//文件映射 hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); struct buf* pint = reinterpret_cast<struct buf*>(Data); for (int i = 0; i < 6; i++) { WaitForSingleObject(empty, INFINITE); //sleep srand((unsigned)time(0)); int tim = rand_1(); Sleep(tim); WaitForSingleObject(mutex, INFINITE); //code pint->buffer[pint->write] = rand_char(); pint->write = (pint->write + 1) % 3; ReleaseMutex(mutex); ReleaseSemaphore(full, 1, NULL); SYSTEMTIME syst; time_t t = time(0); GetSystemTime(&syst); char tmpBuf[10]; strftime(tmpBuf, 10, "%H:%M:%S", localtime(&t)); (int)GetCurrentProcessId(), pint->buffer[0], pint->buffer[1], pint->buffer[2], tmpBuf, syst.wMilliseconds); fflush(stdout); } UnmapViewOfFile(Data);//解除映射 Data = NULL; CloseHandle(mutex); CloseHandle(empty); CloseHandle(full); } void con()//消费者 { HANDLE mutex = CreateMutex(NULL, FALSE, "MYMUTEX"); HANDLE empty = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "MYEMPTY"); HANDLE full = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "MYFULL"); HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "myfilemap"); LPVOID Data = MapViewOfFile(//文件映射 hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); struct buf* pint = reinterpret_cast<struct buf*>(Data); for (int i = 0; i < 4; i++) { WaitForSingleObject(full, INFINITE); //sleep srand((unsigned)time(0)); int tim = rand_1(); Sleep(tim); WaitForSingleObject(mutex, INFINITE); pint->buffer[pint->read] = ' '; pint->read = (pint->read + 1) % 3; ReleaseMutex(mutex); ReleaseSemaphore(empty, 1, NULL); //code time_t t = time(0); char tmpBuf[10]; SYSTEMTIME syst; GetSystemTime(&syst); strftime(tmpBuf, 10, "%H:%M:%S", localtime(&t)); (int)GetCurrentProcessId(), pint->buffer[0], pint->buffer[1], pint->buffer[2], tmpBuf, syst.wMilliseconds); fflush(stdout); } UnmapViewOfFile(Data);//解除映射 Data = NULL; CloseHandle(mutex); CloseHandle(empty); CloseHandle(full); } int main(int argc, char* argv[]) { int nCloneID = 20; if (argc > 1) { sscanf(argv[1], "%d", &nCloneID); } if (nCloneID < 2)//生产者进程 { pro(); } else if (nCloneID < 5)//消费者进程 { con(); } else//主进程 { HANDLE hMap = CreateFileMapping( NULL, NULL, PAGE_READWRITE, 0, sizeof(struct buf), "myfilemap"); if (hMap != INVALID_HANDLE_VALUE) { LPVOID Data = MapViewOfFile(//文件映射 hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (Data != NULL) { ZeroMemory(Data, sizeof(struct buf)); } struct buf* pnData = reinterpret_cast<struct buf*>(Data); pnData->read = 0; pnData->write = 0; memset(pnData->buffer, 0, sizeof(pnData->buffer)); UnmapViewOfFile(Data);//解除映射 Data = NULL; } HANDLE empty = CreateSemaphore(NULL, 3, 3, "MYEMPTY"); HANDLE full = CreateSemaphore(NULL, 0, 3, "MYFULL"); for (int i = 0; i < 5; i++)//创建子进程 StartClone(i); WaitForMultipleObjects(5, handleOfProcess, TRUE, INFINITE); CloseHandle(empty); CloseHandle(full); } } |
Linux版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
//实验三:生产者消费者 #include<string.h> #include <sys/time.h> #include<stdio.h> #include<sys/types.h> #include<unistd.h> #include<stdlib.h> #include<sys/sem.h> #include<sys/select.h> #include<sys/wait.h> #include<sys/ipc.h> #include<sys/shm.h> #include<time.h> #define SEM_ID1 225 #define SEM_ID2 97 #define SEM_ID3 234 #define SHMKEY 75 struct buf { char buffer[3]; int read; int write; }; int rand_1() { return rand() % 300; } void sleep_ms(int s) { usleep(s * 10000); } char* cur_time() { time_t timep; time(&timep); return ctime(&timep); } char rand_char() { return rand() % 26 + 'A'; } void P(int s)//p操作 { struct sembuf sem_op; sem_op.sem_num = 0; sem_op.sem_op = -1; sem_op.sem_flg = 0; semop(s, &sem_op, 1); } void V(int s)//v操作 { struct sembuf sem_op; sem_op.sem_num = 0; sem_op.sem_op = 1; sem_op.sem_flg = 0; semop(s, &sem_op, 1); } void pro()//生产者 { int tim, shmid, i = 6; int sem_mutex, sem_empty, sem_full; void* addr; struct buf* pint; struct sembuf sem_op; struct timeval tv; sem_mutex = semget(SEM_ID1, 1, 0600); sem_empty = semget(SEM_ID2, 1, 0600); sem_full = semget(SEM_ID3, 1, 0600); shmid = shmget(SHMKEY, sizeof(struct buf), 0777); addr = shmat(shmid, 0, 0); while (i--) { gettimeofday(&tv, NULL); srand((unsigned)tv.tv_usec); tim = rand_1(); sleep_ms(tim); //P(empty) P(sem_empty); //P(mutex) P(sem_mutex); pint = (struct buf*)addr; // pint[semctl(sem_full,0,GETVAL)]=time; pint->buffer[pint->write] = rand_char(); pint->write = (pint->write + 1) % 3; getpid(), pint->buffer[0], pint->buffer[1], pint->buffer[2], tv.tv_sec, tv.tv_usec); //V(mutex) V(sem_mutex); //V(full) V(sem_full); } shmdt(addr); } void con()//消费者 { int tim, shmid, i = 4; int sem_mutex, sem_empty, sem_full; void* addr; struct buf* pint; struct sembuf sem_op; struct timeval tv; sem_mutex = semget(SEM_ID1, 1, 0600); sem_empty = semget(SEM_ID2, 1, 0600); sem_full = semget(SEM_ID3, 1, 0600); shmid = shmget(SHMKEY, sizeof(struct buf), 0777); addr = shmat(shmid, 0, 0); while (i--) { gettimeofday(&tv, NULL); srand((unsigned)tv.tv_usec); tim = rand_1(); sleep_ms(tim); //P(full) P(sem_full); //P(mutex) P(sem_mutex); pint = (struct buf*)addr; pint->buffer[pint->read] = ' '; pint->read = (pint->read + 1) % 3; getpid(), pint->buffer[0], pint->buffer[1], pint->buffer[2], tv.tv_sec, tv.tv_usec); //V(mutex) V(sem_mutex); //V(empty) V(sem_empty); } shmdt(addr); } int main() { int sem_mutex, sem_empty, sem_full, shmid; void* addr; union semun { int val; }empty, full, mutex; //建立信号量 sem_mutex = semget(SEM_ID1, 1, IPC_CREAT | 0600); sem_empty = semget(SEM_ID2, 1, IPC_CREAT | 0600); sem_full = semget(SEM_ID3, 1, IPC_CREAT | 0600); full.val = 0; empty.val = 3; mutex.val = 1; semctl(sem_mutex, 0, SETVAL, mutex); semctl(sem_empty, 0, SETVAL, empty); semctl(sem_full, 0, SETVAL, full); //建立共享内存并进行映射 shmid = shmget(SHMKEY, sizeof(struct buf), 0777 | IPC_CREAT); if (-1 == shmid) { printf("建立共享内存失败\n"); exit(0); } addr = shmat(shmid, 0, 0); memset(addr, 0, sizeof(struct buf)); //执行生产者进程 for (int i = 0; i < 2; i++) if (fork() == 0) { pro(); exit(0); } //执行消费者进程 for (int i = 0; i < 3; i++) if (fork() == 0) { con(); exit(0); } while (-1 != wait(0)); semctl(sem_mutex, 0, IPC_RMID); semctl(sem_empty, 0, IPC_RMID); semctl(sem_full, 0, IPC_RMID); shmdt(addr); } |
SSL 认证之后,request.getScheme()获取不到https的问题记录
通过浏览器输入https://www.xxx.com,request.getScheme()获取到的确实http而不是https
通过request.getRequestURL()拿到的也是http://www.xxx.com
分析原因,是因为用nginx+tomcat部署web服务,tomcat接受到的请求都是来自于nginx的http请求。
1 2 3 4 5 |
request.getScheme() //总是 http,而不是实际的http或https request.isSecure() //总是false(因为总是http) request.getRemoteAddr() //总是 nginx 请求的 IP,而不是用户的IP request.getRequestURL() //总是 nginx 请求的URL 而不是用户实际请求的 URL response.sendRedirect( 相对url ) //总是重定向到 http 上 (因为认为当前是 http 请求) |
vc++6.0 远程调试
VS2005 vs2008 vs2010 vs2012 远程调试上篇已经讲过,这里再讲下VC++6.0开发环境下的远程调试能力,仅需下面4步即可,更方便的就接着后面的5-6步。
因为目标程序需要在有采集卡等相关硬件支持下的工控机上工作,工控机上面一般没有调试环境也不会放置源代码(出于保密)。假如工控机上的目标程序运行中出了问题,就需要有调试环境却无法安装采集卡等硬件的笔记本上进行远程调试。
一。远程调试条件
1.两者之间使用有线或无线连网。
2.目标机器与本机的调试机器连接通讯,需要四个文件:MSVCMON.EXE、DM.DLL、TLN0T.DLL和MSDIS110.DLL。它们可在VC6安装文件夹的Common/MSDEV98/Bin下面找到。
继续阅读 »
libuv 在win10 vs各个版本编译静态库
01 环境
libuv使用git管理代码,使用gyp管理工程文件。git、python2.x必须。
环境描述:
win10x64企业版本(10.0.14393),
vs2005–vs2015,
python2.7.6,
git(version 1.9.5.chromium.6)。
git和python建议使用更高版本。
因为下载gyp管理工具需求翻墙,需要vpn。自己有美国的vps,可以自己搭建。
官网:http://libuv.org/
github源码:https://github.com/libuv/libuv
02 源码下载
命令提示符窗口输入:
继续阅读 »
近期评论