├── .gitattributes ├── .gitignore ├── .vscode ├── c_cpp_properties.json ├── head.h ├── launch.json └── tasks.json ├── CppProperties.json ├── LICENSE ├── Linux ├── EX_2 │ ├── ChildProcess.cpp │ ├── StartProcess.cpp │ └── Test │ │ ├── Exec.cpp │ │ ├── GetTime.cpp │ │ └── goodNight.cpp ├── EX_3 │ ├── Consumer.cpp │ ├── Producer.cpp │ ├── README.md │ ├── Test │ │ ├── GetPreSharedMem.cpp │ │ ├── InputSharedMem.cpp │ │ ├── OurRandomIsTheBest.cpp │ │ ├── README.md │ │ ├── Sema_opP.cpp │ │ ├── Sema_opV.cpp │ │ ├── ShareMem.cpp │ │ ├── ShgetTest.cpp │ │ └── rand.cpp │ ├── main.cpp │ └── posix.b ├── EX_4 │ └── README.md ├── EX_5 │ ├── README.md │ ├── Test │ │ ├── SwitchType.cpp │ │ ├── my_MKdir.cpp │ │ └── softLinkTime.cpp │ └── myCp.cpp └── README.md ├── README.md └── Windows ├── EX_2 ├── ChildProcess.cpp ├── ChildProcess.exe ├── StartProcess.cpp └── StartProcess.exe ├── EX_3 ├── Producer_Consumer.cpp ├── Producer_Consumer.exe ├── Producer_Consumer_20.exe ├── README.md ├── Test │ ├── Sema.cpp │ ├── Sema.exe │ ├── currentHandle.cpp │ ├── currentHandle.exe │ ├── sharedMemory.cpp │ └── sharedMemory.exe ├── out └── out.txt ├── EX_4 ├── Ex4_Arm.exe ├── Ex4_x64.exe ├── Ex4_x86.exe ├── ProcessShot.cpp ├── ProcessShot.exe ├── README.md └── Test │ └── WinBaseName.cpp ├── EX_5 ├── README.md ├── Test │ ├── CopyDir.cpp │ ├── CopyFile.cpp │ ├── PrintFileName.cpp │ ├── PrintFileName.exe │ ├── functionPointer.cpp │ └── functionPointer.exe ├── myCp.cpp ├── myCp.exe └── mycp_enhanced.cpp ├── OSD-Windows.sln ├── OSD-Windows.vcxproj ├── OSD-Windows.vcxproj.filters ├── README.md └── Test └── wmain.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb 341 | 342 | *.out -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Win32", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [ 9 | "_DEBUG", 10 | "UNICODE", 11 | "_UNICODE" 12 | ], 13 | "cStandard": "c11", 14 | "cppStandard": "c++17" 15 | } 16 | ], 17 | "version": 4 18 | } -------------------------------------------------------------------------------- /.vscode/head.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | clock_t NOWTIME; 5 | static void before(void) __attribute__((constructor)); 6 | static void after(void) __attribute__((destructor)); 7 | static void before() 8 | { 9 | NOWTIME = clock(); 10 | } 11 | static void after() 12 | { 13 | printf("------------------------------------------"); 14 | printf("\n程序运行完毕,用时: %ld 毫秒\n", (clock() - NOWTIME)*1000/CLOCKS_PER_SEC); 15 | printf("此程序最后编译日期: %s %s \n", __DATE__, __TIME__); 16 | const char temp[3] = "©"; 17 | printf("%s 2020 王梓丞\n", temp); 18 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "make", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/main.out", 12 | "args": [], 13 | "stopAtEntry": false, 14 | "cwd": "${workspaceFolder}", 15 | "environment": [], 16 | "externalConsole": false, 17 | "internalConsoleOptions": "neverOpen", 18 | "MIMode": "gdb", 19 | "setupCommands": [ 20 | { 21 | "description": "为 gdb 启用整齐打印", 22 | "text": "-enable-pretty-printing", 23 | "ignoreFailures": true 24 | } 25 | ], 26 | "preLaunchTask": "make" 27 | }, 28 | { 29 | "console": "externalTerminal", //MSVC一般是GBK,使用外置中段不会乱码 30 | "name": "MSVC Debug", 31 | "type": "cppvsdbg", 32 | "request": "launch", 33 | "program": "${fileDirname}\\${fileBasenameNoExtension}.exe", 34 | "args": [], 35 | "stopAtEntry": false, 36 | "cwd": "${workspaceFolder}", 37 | "externalConsole": false, 38 | "preLaunchTask": "cl.exe build active file", 39 | "postDebugTask": "clear" 40 | }, 41 | { 42 | "console": "externalTerminal", //MSVC一般是GBK,使用外置中段不会乱码 43 | "name": "MSVC Default Env", 44 | "type": "cppvsdbg", 45 | "request": "launch", 46 | "program": "${fileDirname}\\${fileBasenameNoExtension}.exe", 47 | "args": [], 48 | "stopAtEntry": false, 49 | "cwd": "${workspaceFolder}", 50 | "externalConsole": false, 51 | "preLaunchTask": "cl.exe with default env", 52 | "postDebugTask": "clear" 53 | }, 54 | { 55 | "name": "Cpp Debug Launch", 56 | "program": "${fileDirname}/${fileBasenameNoExtension}.out", 57 | "miDebuggerPath": "/usr/bin/gdb", 58 | "type": "cppdbg", 59 | "request": "launch", 60 | "args": [], 61 | "stopAtEntry": false, 62 | "cwd": "${fileDirname}", 63 | "environment": [], 64 | "externalConsole": false, 65 | "internalConsoleOptions": "neverOpen", 66 | "MIMode": "gdb", 67 | "setupCommands": [ 68 | { 69 | "text": "-enable-pretty-printing", 70 | "ignoreFailures": true 71 | } 72 | ], 73 | "preLaunchTask": "C/C++: g++ build active file", 74 | } 75 | ] 76 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // 有关 tasks.json 格式的文档,请参见 3 | // https://go.microsoft.com/fwlink/?LinkId=733558 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "shell", 8 | "label": "Copyright", 9 | "command": "g++", 10 | "linux": { 11 | "args": [ 12 | "-g", 13 | "${file}", 14 | "-include", 15 | "${workspaceRoot}/.vscode/head.h", 16 | "-o", 17 | "${fileDirname}/${fileBasenameNoExtension}.out" 18 | ] 19 | }, 20 | "windows": { 21 | "args": [ 22 | "-g", 23 | "${file}", 24 | "-include", 25 | "${workspaceRoot}/.vscode/head.h", 26 | "-o", 27 | "${fileDirname}/${fileBasenameNoExtension}.exe" 28 | ] 29 | }, 30 | }, 31 | { 32 | "type": "shell", 33 | "label": "C/C++: g++ build active file", 34 | "command": "g++", 35 | "args": [ 36 | "-g", 37 | "${file}", 38 | "-o", 39 | "${fileDirname}\\${fileBasenameNoExtension}.exe" 40 | ], 41 | "linux": { 42 | "args": [ 43 | "-g", 44 | "${file}", 45 | "-o", 46 | "${fileDirname}/${fileBasenameNoExtension}.out" 47 | ] 48 | }, 49 | "problemMatcher": [ 50 | "$gcc" 51 | ], 52 | "group": "build" 53 | }, 54 | { 55 | "type": "shell", 56 | "label": "cl.exe build active file", 57 | "command": "cl.exe", 58 | "args": [ 59 | "/Zi", 60 | "/EHsc", 61 | "/Fe:", 62 | "${fileDirname}\\${fileBasenameNoExtension}.exe", 63 | "${file}" 64 | ], 65 | "problemMatcher": [ 66 | "$msCompile" 67 | ], 68 | "group": { 69 | "kind": "build", 70 | "isDefault": true 71 | }, 72 | //将MSVC需要的环境拷到这里 73 | "options": { 74 | "env": { 75 | "OneDriveConsumer": "C:\\Users\\Rinka\\OneDrive", 76 | "ProgramFiles(x86)": "C:\\Program Files (x86)", 77 | "Path": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX86\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\VC\\VCPackages;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\MSBuild\\Current\\bin\\Roslyn;C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v10.0A\\bin\\NETFX 4.8 Tools\\;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.18362.0\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\\\MSBuild\\Current\\Bin;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX86\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\VC\\VCPackages;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\MSBuild\\Current\\bin\\Roslyn;C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v10.0A\\bin\\NETFX 4.8 Tools\\;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.18362.0\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\\\MSBuild\\Current\\Bin;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX86\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\VC\\VCPackages;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\MSBuild\\Current\\bin\\Roslyn;C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v10.0A\\bin\\NETFX 4.8 Tools\\;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.18362.0\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\\\MSBuild\\Current\\Bin;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\bin\\HostX86\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\VC\\VCPackages;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\CommonExtensions\\Microsoft\\TestWindow;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\MSBuild\\Current\\bin\\Roslyn;C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v10.0A\\bin\\NETFX 4.8 Tools\\;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.18362.0\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\\\MSBuild\\Current\\Bin;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files\\Git\\cmd;C:\\Program Files\\dotnet\\;C:\\ProgramData\\chocolatey\\bin;C:\\ProgramData\\chocolatey\\lib\\gsudo\\bin\\;C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\170\\Tools\\Binn\\;C:\\Program Files\\nodejs\\;C:\\Users\\Rinka\\scoop\\shims;C:\\Users\\Rinka\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files\\Bandizip\\;C:\\Users\\Rinka\\AppData\\Local\\Programs\\Fiddler;C:\\Users\\Rinka\\AppData\\Roaming\\npm;C:\\Users\\Rinka\\.dotnet\\tools;C:\\Users\\Rinka\\AppData\\Local\\Programs\\Microsoft VS Code\\bin;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files\\Git\\cmd;C:\\Program Files\\dotnet\\;C:\\ProgramData\\chocolatey\\bin;C:\\ProgramData\\chocolatey\\lib\\gsudo\\bin\\;C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\170\\Tools\\Binn\\;C:\\Program Files\\nodejs\\;C:\\Users\\Rinka\\scoop\\shims;C:\\Users\\Rinka\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files\\Bandizip\\;C:\\Users\\Rinka\\AppData\\Local\\Programs\\Fiddler;C:\\Users\\Rinka\\AppData\\Roaming\\npm;C:\\Users\\Rinka\\.dotnet\\tools;C:\\Users\\Rinka\\AppData\\Local\\Programs\\Microsoft VS Code\\bin", 78 | "ProgramW6432": "C:\\Program Files", 79 | "NETFXSDKDir": "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\", 80 | "ChocolateyInstall": "C:\\ProgramData\\chocolatey", 81 | "PROCESSOR_IDENTIFIER": "Intel64 Family 6 Model 126 Stepping 5, GenuineIntel", 82 | "VCToolsRedistDir": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Redist\\MSVC\\14.28.29325\\", 83 | "TMP": "C:\\Users\\Rinka\\AppData\\Local\\Temp", 84 | "PROCESSOR_ARCHITECTURE": "AMD64", 85 | "DriverData": "C:\\Windows\\System32\\Drivers\\DriverData", 86 | "PATHEXT": ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL", 87 | "VSINSTALLDIR": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\", 88 | "WindowsSdkVerBinPath": "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.18362.0\\", 89 | "PROCESSOR_REVISION": "7e05", 90 | "UniversalCRTSdkDir": "C:\\Program Files (x86)\\Windows Kits\\10\\", 91 | "__DOTNET_PREFERRED_BITNESS": "32", 92 | "VSCODE_GIT_IPC_HANDLE": "\\\\.\\pipe\\vscode-git-e7fe63f6f9-sock", 93 | "Framework40Version": "v4.0", 94 | "VSCODE_GIT_ASKPASS_MAIN": "c:\\Users\\Rinka\\AppData\\Local\\Programs\\Microsoft VS Code\\resources\\app\\extensions\\git\\dist\\askpass-main.js", 95 | "CommonProgramFiles": "C:\\Program Files\\Common Files", 96 | "WindowsSDK_ExecutablePath_x86": "C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v10.0A\\bin\\NETFX 4.8 Tools\\", 97 | "ChocolateyLastPathUpdate": "132524061654595195", 98 | "FPS_BROWSER_APP_PROFILE_STRING": "Internet Explorer", 99 | "FPS_BROWSER_USER_PROFILE_STRING": "Default", 100 | "LOGONSERVER": "\\\\SURFACE-NANA", 101 | "TEMP": "C:\\Users\\Rinka\\AppData\\Local\\Temp", 102 | "WindowsSdkDir": "C:\\Program Files (x86)\\Windows Kits\\10\\", 103 | "USERNAME": "Rinka", 104 | "SystemRoot": "C:\\WINDOWS", 105 | "DevEnvDir": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\", 106 | "CHROME_CRASHPAD_PIPE_NAME": "\\\\.\\pipe\\crashpad_9616_SRQNTDJMDFSQVDLS", 107 | "VCIDEInstallDir": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\IDE\\VC\\", 108 | "WindowsSDK_ExecutablePath_x64": "C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v10.0A\\bin\\NETFX 4.8 Tools\\x64\\", 109 | "VSCODE_GIT_ASKPASS_NODE": "C:\\Users\\Rinka\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe", 110 | "VSCMD_ARG_HOST_ARCH": "x86", 111 | "OneDrive": "C:\\Users\\Rinka\\OneDrive", 112 | "VCToolsVersion": "14.28.29333", 113 | "INCLUDE": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\include;C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\ucrt;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\cppwinrt;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\include;C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\ucrt;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\cppwinrt;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\include;C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\ucrt;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\cppwinrt;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\include;C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\ucrt;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\shared;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\um;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\winrt;C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.18362.0\\cppwinrt", 114 | "FrameworkDir32": "C:\\Windows\\Microsoft.NET\\Framework\\", 115 | "WindowsLibPath": "C:\\Program Files (x86)\\Windows Kits\\10\\UnionMetadata\\10.0.18362.0;C:\\Program Files (x86)\\Windows Kits\\10\\References\\10.0.18362.0", 116 | "FrameworkVersion": "v4.0.30319", 117 | "VSCMD_ARG_app_plat": "Desktop", 118 | "ProgramData": "C:\\ProgramData", 119 | "LANG": "zh_CN.UTF-8", 120 | "GIT_ASKPASS": "c:\\Users\\Rinka\\AppData\\Local\\Programs\\Microsoft VS Code\\resources\\app\\extensions\\git\\dist\\askpass.sh", 121 | "HOMEPATH": "\\Users\\Rinka", 122 | "COMPUTERNAME": "SURFACE-NANA", 123 | "WindowsSdkBinPath": "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\", 124 | "FrameworkVersion32": "v4.0.30319", 125 | "ALLUSERSPROFILE": "C:\\ProgramData", 126 | "CommonProgramW6432": "C:\\Program Files\\Common Files", 127 | "VCToolsInstallDir": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\", 128 | "VCINSTALLDIR": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\", 129 | "VS160COMNTOOLS": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\", 130 | "ExtensionSdkDir": "C:\\Program Files (x86)\\Microsoft SDKs\\Windows Kits\\10\\ExtensionSDKs", 131 | "__VSCMD_PREINIT_VS160COMNTOOLS": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\Common7\\Tools\\", 132 | "LIBPATH": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86\\store\\references;C:\\Program Files (x86)\\Windows Kits\\10\\UnionMetadata\\10.0.18362.0;C:\\Program Files (x86)\\Windows Kits\\10\\References\\10.0.18362.0;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86\\store\\references;C:\\Program Files (x86)\\Windows Kits\\10\\UnionMetadata\\10.0.18362.0;C:\\Program Files (x86)\\Windows Kits\\10\\References\\10.0.18362.0;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86\\store\\references;C:\\Program Files (x86)\\Windows Kits\\10\\UnionMetadata\\10.0.18362.0;C:\\Program Files (x86)\\Windows Kits\\10\\References\\10.0.18362.0;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86\\store\\references;C:\\Program Files (x86)\\Windows Kits\\10\\UnionMetadata\\10.0.18362.0;C:\\Program Files (x86)\\Windows Kits\\10\\References\\10.0.18362.0;C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319", 133 | "SESSIONNAME": "Console", 134 | "UCRTVersion": "10.0.18362.0", 135 | "TERM_PROGRAM": "vscode", 136 | "CommonProgramFiles(x86)": "C:\\Program Files (x86)\\Common Files", 137 | "HOMEDRIVE": "C:", 138 | "windir": "C:\\WINDOWS", 139 | "SystemDrive": "C:", 140 | "NUMBER_OF_PROCESSORS": "8", 141 | "OS": "Windows_NT", 142 | "__DOTNET_ADD_32BIT": "1", 143 | "CommandPromptType": "Native", 144 | "ComSpec": "C:\\WINDOWS\\system32\\cmd.exe", 145 | "ORIGINAL_XDG_CURRENT_DESKTOP": "undefined", 146 | "ProgramFiles": "C:\\Program Files", 147 | "HOME": "C:\\Users\\Rinka", 148 | "PSModulePath": "C:\\Users\\Rinka\\Documents\\WindowsPowerShell\\Modules;C:\\Program Files\\WindowsPowerShell\\Modules;C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\Modules", 149 | "WindowsSDKLibVersion": "10.0.18362.0\\", 150 | "LIB": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86;C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\lib\\um\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\ucrt\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\um\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86;C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\lib\\um\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\ucrt\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\um\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86;C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\lib\\um\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\ucrt\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\um\\x86;C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\BuildTools\\VC\\Tools\\MSVC\\14.28.29333\\lib\\x86;C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\lib\\um\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\ucrt\\x86;C:\\Program Files (x86)\\Windows Kits\\10\\lib\\10.0.18362.0\\um\\x86", 151 | "PROMPT": "$P$G", 152 | "COLORTERM": "truecolor", 153 | "ChocolateyToolsLocation": "C:\\tools", 154 | "APPDATA": "C:\\Users\\Rinka\\AppData\\Roaming", 155 | "USERDOMAIN": "SURFACE-NANA", 156 | "PROCESSOR_LEVEL": "6", 157 | "USERPROFILE": "C:\\Users\\Rinka", 158 | "LOCALAPPDATA": "C:\\Users\\Rinka\\AppData\\Local", 159 | "VisualStudioVersion": "16.0", 160 | "WindowsSDKVersion": "10.0.18362.0\\", 161 | "VSCMD_VER": "16.8.3", 162 | "TERM_PROGRAM_VERSION": "1.52.1", 163 | "__VSCMD_PREINIT_PATH": "C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files\\Git\\cmd;C:\\Program Files\\dotnet\\;C:\\ProgramData\\chocolatey\\bin;C:\\ProgramData\\chocolatey\\lib\\gsudo\\bin\\;C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\170\\Tools\\Binn\\;C:\\Program Files\\nodejs\\;C:\\Users\\Rinka\\scoop\\shims;C:\\Users\\Rinka\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files\\Bandizip\\;C:\\Users\\Rinka\\AppData\\Local\\Programs\\Fiddler;C:\\Users\\Rinka\\AppData\\Roaming\\npm;C:\\Users\\Rinka\\.dotnet\\tools;C:\\Users\\Rinka\\AppData\\Local\\Programs\\Microsoft VS Code\\bin;C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\;C:\\WINDOWS\\System32\\OpenSSH\\;C:\\Program Files\\Git\\cmd;C:\\Program Files\\dotnet\\;C:\\ProgramData\\chocolatey\\bin;C:\\ProgramData\\chocolatey\\lib\\gsudo\\bin\\;C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\170\\Tools\\Binn\\;C:\\Program Files\\nodejs\\;C:\\Users\\Rinka\\scoop\\shims;C:\\Users\\Rinka\\AppData\\Local\\Microsoft\\WindowsApps;C:\\Program Files\\Bandizip\\;C:\\Users\\Rinka\\AppData\\Local\\Programs\\Fiddler;C:\\Users\\Rinka\\AppData\\Roaming\\npm;C:\\Users\\Rinka\\.dotnet\\tools;C:\\Users\\Rinka\\AppData\\Local\\Programs\\Microsoft VS Code\\bin", 164 | "USERDOMAIN_ROAMINGPROFILE": "SURFACE-NANA", 165 | "FrameworkDir": "C:\\Windows\\Microsoft.NET\\Framework\\", 166 | "PUBLIC": "C:\\Users\\Public", 167 | "VSCMD_ARG_TGT_ARCH": "x86", 168 | "__VSCMD_PREINIT_VCToolsVersion": "14.28.29333" 169 | } 170 | } 171 | }, 172 | { 173 | "type": "shell", 174 | "label": "cl.exe with default env", 175 | "command": "cl.exe", 176 | "args": [ 177 | "/Zi", 178 | "/EHsc", 179 | "/Fe:", 180 | "${fileDirname}\\${fileBasenameNoExtension}.exe", 181 | "${file}" 182 | ], 183 | "problemMatcher": [ 184 | "$msCompile" 185 | ], 186 | "group": { 187 | "kind": "build", 188 | "isDefault": true 189 | }, 190 | }, 191 | { 192 | "label": "clear", 193 | "type": "shell", 194 | "command": "rm", 195 | "args": [ 196 | "${fileDirname}\\*.pdb,*.pdb,${fileDirname}\\*.ilk,*.ilk,${fileDirname}\\*.obj,*.obj", 197 | "-Force" 198 | ], 199 | "group": "none", 200 | "problemMatcher": [] 201 | }, 202 | { 203 | "label": "make", 204 | "type": "shell", 205 | "command": "make", 206 | "args": [ 207 | "build" 208 | ], 209 | "group": "none", 210 | "problemMatcher": [] 211 | } 212 | ] 213 | } -------------------------------------------------------------------------------- /CppProperties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "inheritEnvironments": [ 5 | "msvc_x64" 6 | ], 7 | "name": "x64-Release", 8 | "includePath": [ 9 | "${env.INCLUDE}", 10 | "${workspaceRoot}\\**" 11 | ], 12 | "defines": [ 13 | "WIN32", 14 | "NDEBUG", 15 | "UNICODE", 16 | "_UNICODE" 17 | ], 18 | "intelliSenseMode": "windows-msvc-x64" 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 BIT-Rinka 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Linux/EX_2/ChildProcess.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(int argc, char const *argv[]) 4 | { 5 | std::cout << "Hi,my name is 王梓丞" << std::endl; 6 | sleep(3); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /Linux/EX_2/StartProcess.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | tm *GetLocalTime() 9 | { 10 | time_t t_mc; //time返回的是机内秒 11 | t_mc = time(NULL); 12 | tm *now_time = localtime(&t_mc); 13 | now_time->tm_year += 1900; //Linux的时间是从1900年1月开始算的机器时间,因此需要修改一下 14 | now_time->tm_mon += 1; 15 | return now_time; 16 | } 17 | 18 | void PrintTime(tm *time) 19 | { 20 | std::cout << time->tm_year << "年" << time->tm_mon << "月" << time->tm_mday << "日 " << time->tm_hour << "时" << time->tm_min << "分" << time->tm_sec << "秒\n" 21 | << std::endl; 22 | } 23 | 24 | time_t GetMSecond() 25 | { 26 | timeval tv; 27 | gettimeofday(&tv, NULL); 28 | return tv.tv_sec * 1000 + tv.tv_usec / 1000; 29 | } 30 | 31 | int main(int argc, char const *argv[]) 32 | { 33 | tm *now_time = GetLocalTime(); 34 | std::cout << "程序开始运行时间:" << std::endl; 35 | PrintTime(now_time); 36 | 37 | pid_t pid = fork(); 38 | 39 | time_t pre_ms = GetMSecond(); 40 | if (pid == 0) 41 | { 42 | if (argc >= 2) 43 | { 44 | char *cargv[] = {NULL}; 45 | execv(argv[1], cargv); 46 | perror("execve"); 47 | } 48 | else 49 | { 50 | std::cout << "too little arguments!" << std::endl; 51 | } 52 | return 0; 53 | } 54 | else if (pid == -1) 55 | { 56 | printf("error!\n"); 57 | } 58 | else 59 | { 60 | int status; 61 | wait(&status); 62 | } 63 | std::cout << "程序结束运行时间:" << std::endl; 64 | now_time = GetLocalTime(); 65 | PrintTime(now_time); 66 | std::cout << "程序运行了" << GetMSecond() - pre_ms << "毫秒" << std::endl; 67 | 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Linux/EX_2/Test/Exec.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char const *argv[]) 7 | { 8 | printf("new process start\n"); 9 | char *cargv[] = {NULL}; 10 | execve("/root/Dev/BIT-OSD/Linux/goodNight.out", cargv, environ);//execve会直接覆盖当前进程 11 | perror("execve"); 12 | printf("Will I show on display?\n"); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /Linux/EX_2/Test/GetTime.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | tm *GetLocalTime() 6 | { 7 | time_t t_mc; //time返回的是机内秒 8 | t_mc = time(NULL); 9 | tm *now_time = localtime(&t_mc); 10 | now_time->tm_year += 1900; //Linux的时间是从1900年1月开始算的机器时间,因此需要修改一下 11 | now_time->tm_mon += 1; 12 | return now_time; 13 | } 14 | time_t GetMSecond() 15 | { 16 | timeval tv; 17 | gettimeofday(&tv, NULL); 18 | return tv.tv_sec*1000+tv.tv_usec/1000; 19 | } 20 | void PrintTime(tm *time) 21 | { 22 | std::cout << time->tm_year << "年" << time->tm_mon << "月" << time->tm_mday << "日 " << time->tm_hour << "时" << time->tm_min << "分" << time->tm_sec << "秒\n" 23 | << std::endl; 24 | } 25 | 26 | int main(int argc, char const *argv[]) 27 | { 28 | timeval pre_tv, aft_tv; 29 | gettimeofday(&pre_tv, NULL); 30 | 31 | clock_t pre_ms = clock(); 32 | tm *now_time = GetLocalTime(); 33 | PrintTime(now_time); 34 | sleep(1); 35 | 36 | std::cout << "运行了" << ((clock() - pre_ms)) << "微秒\n" 37 | << std::endl; 38 | std::cout << "运行了" << ((clock() - pre_ms)) << "微秒\n" 39 | << std::endl; 40 | gettimeofday(&aft_tv, NULL); 41 | 42 | //gettimeofday的方法得到的微秒会进位到秒 但是好像得不到毫秒 43 | std::cout << "运行了" << (aft_tv.tv_sec - pre_tv.tv_sec) * 1000000 + aft_tv.tv_usec - pre_tv.tv_usec << "毫秒\n" 44 | << std::endl; 45 | std::cout << "运行了" << clock()-pre_ms << "微秒\n" 46 | << std::endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Linux/EX_2/Test/goodNight.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main(int argc, char const *argv[]) 4 | { 5 | printf("Good Night!\n"); 6 | sleep(1); 7 | printf("I Get Up!\n"); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /Linux/EX_3/Consumer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define BUFFER_SIZE 4 9 | #define CONSUMER_NUM 4 10 | #define PRODUCER_NUM 3 11 | 12 | int BUFFER_SHMID = -1; 13 | int POINTER_SHMID = -1; 14 | int SEMID = -1; 15 | //规定信号序列号0是mutex=1,1是full=0,2是empty=BUFFER_SIZE 16 | enum 17 | { 18 | mutex_i, 19 | full_i, 20 | empty_i 21 | }; 22 | 23 | void P(int i) 24 | { 25 | sembuf op; 26 | op.sem_flg = 0; 27 | op.sem_num = i; 28 | op.sem_op = -1; 29 | semop(SEMID, &op, 1); 30 | } 31 | void V(int i) 32 | { 33 | sembuf op; 34 | op.sem_flg = 0; 35 | op.sem_num = i; 36 | op.sem_op = +1; 37 | semop(SEMID, &op, 1); 38 | } 39 | void PrintBuffer(char *buffer_addr) 40 | { 41 | for (int i = 0; i < BUFFER_SIZE; i++) 42 | { 43 | cout << buffer_addr[i]; 44 | } 45 | cout << endl; 46 | } 47 | 48 | int main(int argc, char const *argv[]) 49 | { 50 | // cout << "I'm Consumer!" << endl; 51 | //初始化 52 | BUFFER_SHMID = atoi(argv[0]); 53 | POINTER_SHMID = atoi(argv[1]); 54 | SEMID = atoi(argv[2]); 55 | 56 | int *pt = (int *)shmat(POINTER_SHMID, NULL, 0); 57 | char *BUFFER = (char *)shmat(BUFFER_SHMID, NULL, 0); 58 | 59 | for (int i = 0; i < 3; i++) 60 | { 61 | srand(clock()); 62 | //随机睡眠 63 | sleep(rand() % 4); 64 | //P full 65 | P(full_i); 66 | 67 | //P mutex 68 | P(mutex_i); 69 | cout << "A Consumer join in!" << endl; 70 | PrintBuffer(BUFFER); 71 | //打印,修改指针 72 | cout << "get:" << BUFFER[*pt] << endl; 73 | BUFFER[*pt] = '/'; 74 | *pt = (*pt + 1) % BUFFER_SIZE; 75 | PrintBuffer(BUFFER); 76 | cout << "------------------" << endl; 77 | //V empty 78 | V(empty_i); 79 | //V mutex 80 | V(mutex_i); 81 | } 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /Linux/EX_3/Producer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | #define BUFFER_SIZE 4 9 | #define CONSUMER_NUM 4 10 | #define PRODUCER_NUM 3 11 | 12 | int BUFFER_SHMID = -1; 13 | int POINTER_SHMID = -1; 14 | int SEMID = -1; 15 | //规定信号序列号0是mutex=1,1是full=0,2是empty=BUFFER_SIZE 16 | enum 17 | { 18 | mutex_i, 19 | full_i, 20 | empty_i 21 | }; 22 | 23 | void P(int i) 24 | { 25 | sembuf op; 26 | op.sem_flg = 0; 27 | op.sem_num = i; 28 | op.sem_op = -1; 29 | semop(SEMID, &op, 1); 30 | } 31 | void V(int i) 32 | { 33 | sembuf op; 34 | op.sem_flg = 0; 35 | op.sem_num = i; 36 | op.sem_op = +1; 37 | semop(SEMID, &op, 1); 38 | } 39 | void PrintBuffer(char *buffer_addr) 40 | { 41 | for (int i = 0; i < BUFFER_SIZE; i++) 42 | { 43 | cout << buffer_addr[i]; 44 | } 45 | cout << endl; 46 | } 47 | int main(int argc, char const *argv[]) 48 | { 49 | // cout << "I'm Producer!" << endl; 50 | //初始化 51 | BUFFER_SHMID = atoi(argv[0]); 52 | POINTER_SHMID = atoi(argv[1]); 53 | SEMID = atoi(argv[2]); 54 | 55 | int *pt = (int *)shmat(POINTER_SHMID, NULL, 0); 56 | char *BUFFER = (char *)shmat(BUFFER_SHMID, NULL, 0); 57 | pt = pt + 1; 58 | 59 | const char *NAME = "WZC"; 60 | 61 | for (int i = 0; i < 4; i++) 62 | { 63 | srand(clock()); 64 | //随机睡眠 65 | sleep(rand() % 4); 66 | //随机选一个字母提交 67 | char c = NAME[rand() % 3]; 68 | 69 | P(empty_i); 70 | P(mutex_i); 71 | 72 | cout << "A Producer join in!" << endl; 73 | PrintBuffer(BUFFER); 74 | //放入字符 75 | BUFFER[*pt] = c; 76 | cout << "put:" << c << endl; 77 | //修改指针 78 | *pt = (*pt + 1) % BUFFER_SIZE; 79 | PrintBuffer(BUFFER); 80 | cout << "------------------" << endl; 81 | V(full_i); 82 | V(mutex_i); 83 | } 84 | 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /Linux/EX_3/README.md: -------------------------------------------------------------------------------- 1 | # 如何做实验三 2 | 在做实验三前,我有一个重大误解,就是:P/V操有Linux原生的函数支持。 3 | 但其实并没有! 4 | 5 | 我们需要通过使用信号`semaphore`一类(注意,这个sig那些不一样)模拟PV。 6 | 7 | > 为什么用的semaphore呢? 8 | 9 | 因为semaphore一族都属于IPC类型,IPC类型的数据结构在声明后**会常驻内存**,即使这个进程退出了,在系统重启之前,创建的IPC结构数据**依然会留在内存当中**! 10 | 11 | *IPC类型由UNIX System V引入,System V类的接口相当于是Liunx除了POSIX接口外的另一个子系统 ~~让我觉得用起来并没有那么正义~~* 12 | 13 | vfork再exec后的进程依然属于父进程 14 | 15 | ## 注意 16 | 17 | 根据同学反馈,在虚拟机里运行的Linux只有在root用户下才能正确运行生产者-消费者,而在其他普通用户下是无法挂载ipc类型的地址的。 18 | 19 | 试试`sudo ./main.out` 20 | -------------------------------------------------------------------------------- /Linux/EX_3/Test/GetPreSharedMem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | int main(int argc, char const *argv[]) 9 | { 10 | if (argc >= 2) 11 | { 12 | int shmid = atoi(argv[1]); 13 | char *test = (char *)shmat(shmid, NULL, 0); 14 | cout << test << endl; 15 | } 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Linux/EX_3/Test/InputSharedMem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | int main(int argc, char const *argv[]) 9 | { 10 | int shmid = shmget(IPC_PRIVATE, 100, IPC_CREAT); 11 | cout << shmid << endl; 12 | char *str = (char *)shmat(shmid, NULL, 0); 13 | if (argc >= 2) 14 | { 15 | strncpy(str, argv[1], 100); 16 | } 17 | else 18 | { 19 | strncpy(str, "Hello My memory\n", 100); 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Linux/EX_3/Test/OurRandomIsTheBest.cpp: -------------------------------------------------------------------------------- 1 | //一个批次: 2 | // srand一次(srand方法的区别) 3 | // 生成十万个0~100内的随机数 4 | // 求标准差,打印 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | #define AMOUNT 100000 12 | #define RANGE 100 13 | /** 14 | * 求平均值 15 | */ 16 | double average(double *x, int len) 17 | { 18 | long long sum = 0; 19 | for (int i = 0; i < len; i++) // 求和 20 | sum += x[i]; 21 | return sum / len; // 得到平均值 22 | } 23 | 24 | /** 25 | * 求方差 26 | */ 27 | double variance(double *x, int len) 28 | { 29 | double sum = 0; 30 | double av = average(x, len); 31 | for (int i = 0; i < len; i++) // 求和 32 | sum += pow(x[i] - av, 2); 33 | return sum / len; // 得到平均值 34 | } 35 | /** 36 | * 求标准差 37 | */ 38 | double STDD(double *x, int len) 39 | { 40 | double var = variance(x, len); 41 | return sqrt(var); // 得到标准差 42 | } 43 | 44 | void TestRand() 45 | { 46 | // int *count = (int *)calloc(AMOUNT, sizeof(int)); 47 | long long deviate = 0; 48 | for (int i = 0; i < 1000; i++) 49 | { 50 | int index = 0; 51 | long long sum = 0; 52 | for (int i = 0; i < AMOUNT; i++) 53 | { 54 | index = rand() % RANGE; 55 | sum += index; 56 | // count[index]++; 57 | } 58 | // cout << "target range:" << RANGE << endl; 59 | deviate += (sum - 495 * (AMOUNT / 10)); 60 | } 61 | 62 | cout << "deviate:" << double(deviate/1000) << endl; 63 | // free(count); 64 | } 65 | 66 | int main(int argc, char const *argv[]) 67 | { 68 | //似乎用clock和time并没有明显差别 69 | cout << "for no srand:" << endl; 70 | TestRand(); 71 | cout << endl 72 | << "-------------------------" << endl; 73 | cout << "for clock:" << endl; 74 | srand(clock()); 75 | TestRand(); 76 | cout << endl 77 | << "-------------------------" << endl; 78 | cout << "for time:" << endl; 79 | srand(time(NULL)); 80 | TestRand(); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /Linux/EX_3/Test/README.md: -------------------------------------------------------------------------------- 1 | # 神奇的事情 2 | ## EX_3 3 | 实验三中Test文件夹里面的`GetPreSharedMem.cpp`和`InputSharedMem.cpp`是一对文件。 4 | `InputSharedMem.cpp`编译后的文件可以接收输入参数`arg[1]`的字符串,并将其复制到一个新的共享内存空间。接着会返回一个值,也就是shmid,共享内存的关键值。 5 | 6 | 而`GetPreSharedMem.cpp`可以通过给出的共享内存的关键值(通过`arg[1]`传递)找到对应内存空间的字符串。 7 | 8 | 所以当你把`InputSharedMem.cpp`输入字符串后返回的id,交给`GetPreSharedMem.cpp`使用,就可以看到之前输入的字符串。 9 | 10 | 6291648 11 | 12 | ```cpp 13 | //InputSharedMem.cpp 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | using namespace std; 21 | int main(int argc, char const *argv[]) 22 | { 23 | int shmid = shmget(IPC_PRIVATE, 100, IPC_CREAT); 24 | cout << shmid << endl; 25 | char *str = (char *)shmat(shmid, NULL, 0); 26 | if (argc >= 2) 27 | { 28 | strncpy(str, argv[1], 100); 29 | } 30 | else 31 | { 32 | strncpy(str, "Hello My memory\n", 100); 33 | } 34 | return 0; 35 | } 36 | 37 | //GetPreSharedMem.cpp 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | using namespace std; 45 | int main(int argc, char const *argv[]) 46 | { 47 | if (argc >= 2) 48 | { 49 | int shmid = atoi(argv[1]); 50 | char *test = (char *)shmat(shmid, NULL, 0); 51 | cout << test << endl; 52 | } 53 | 54 | return 0; 55 | } 56 | ``` 57 | 58 | 不使用 59 | ```cpp 60 | shmctl(shmid,IPC_RMID,0); 61 | ``` 62 | 删除内存,他就会一直存在 63 | 64 | 只能通过shell命令 65 | `ipcrm`来删除 66 | 67 | 通过这个来查系统的共享内存限制: 68 | ```shell 69 | > ipcs -lq 70 | 71 | ------ Messages Limits -------- 72 | max queues system wide = 32000 73 | max size of message (bytes) = 8192 74 | default max size of queue (bytes) = 16384 75 | ``` 76 | 77 | 可以通过P操作的代码`Linux/Test/Sema_opP.cpp`和V操作的代码`Linux/Test/Sema_opV.cpp`模拟PV操作 78 | 79 | --- 80 | wait()不对睡眠的子进程奏效?即使子进程处于睡眠状态,wait也依然可能认为子进程其实是结束了的? 81 | > 一个wait只等一个子进程 -------------------------------------------------------------------------------- /Linux/EX_3/Test/Sema_opP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | int main(int argc, char const *argv[]) 5 | { 6 | //IPC的对象都放置在共享内存中 7 | int sem_id = semget(0, 2, IPC_CREAT); 8 | 9 | std::cout << "信号量id:" << sem_id << std::endl; //打印sem id到控制台,供其他进程使用 10 | 11 | semctl(sem_id, 0, SETVAL, 2); //对0号操作 12 | semctl(sem_id, 1, SETVAL, 4); //对1号操作 13 | std::cout << semctl(sem_id, 0, GETVAL) << '\n' 14 | << semctl(sem_id, 1, GETVAL) << std::endl; 15 | 16 | sembuf a; 17 | a.sem_num = 1; 18 | a.sem_op = -1;//sem进行一次-1操作 19 | a.sem_flg = 0; 20 | // a.sem_flg = IPC_NOWAIT;//flg只受IPC_NOWAIT和SEM_UNDO两种值影响。如果是IPC_NOWAIT的话,信号量值减为0后进程不会阻塞,但信号量也不会变为负数 21 | 22 | int i = 0; 23 | while (1) 24 | { 25 | semop(sem_id, &a, 1); 26 | 27 | std::cout << semctl(sem_id, 0, GETVAL) << '\n' 28 | << semctl(sem_id, 1, GETVAL) << std::endl; //如果sem的值变为0,则进程会阻塞在这 29 | std::cout << "第" << ++i << "次运行" << std::endl; 30 | sleep(1); 31 | } 32 | 33 | semctl(sem_id, 0, IPC_RMID); //删除信号;使用 IPC_RMID时,semnum参数项会被忽略 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /Linux/EX_3/Test/Sema_opV.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | int main(int argc, char const *argv[]) 6 | { 7 | int sem_id = 0; 8 | if (argc >= 2) 9 | { 10 | sem_id = atoi(argv[1]); 11 | } 12 | else 13 | { 14 | std::cout << "请输入信号量id" << std::endl; 15 | std::cin >> sem_id; 16 | } 17 | 18 | sembuf op; 19 | op.sem_flg = 0; 20 | op.sem_num = 1; 21 | op.sem_op = +1; 22 | while (1) 23 | { 24 | std::cout << "输入回车以让信号量+1" << std::endl; 25 | semop(sem_id, &op, 1); 26 | getchar(); 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Linux/EX_3/Test/ShareMem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | int main(int argc, char const *argv[]) 8 | { 9 | int size_shm = 100; 10 | 11 | int m_key = shmget(IPC_PRIVATE, size_shm, IPC_CREAT); 12 | pid_t pt = fork(); 13 | if (pt == 0) 14 | { 15 | //son 16 | sleep(1); 17 | char *addr = (char *)shmat(m_key, NULL, 0);//这个可能会因为父进程没有把值赋进去而导致输出空值 18 | std::cout< 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | int main(int argc, char const *argv[]) 9 | { 10 | int shmid = shmget(IPC_PRIVATE, 100, IPC_CREAT); 11 | cout << shmid << endl; 12 | 13 | shmid = shmget(2, 100, 0); 14 | cout << shmid << endl; 15 | 16 | char *str = (char *)calloc(100, 1); 17 | char *temp=(char*)shmat(shmid, NULL, 0); 18 | 19 | strncpy(str, "Hello! My son!", 100); 20 | 21 | cout<<&str< 2 | #include 3 | #include 4 | #include 5 | int main(int argc, char const *argv[]) 6 | { 7 | srand(clock()); 8 | int *count = (int *)calloc(100, sizeof(int)); 9 | if (count == NULL) 10 | { 11 | perror("calloc error"); 12 | return -1; 13 | } 14 | 15 | for (int i = 0; i < 100; i++) 16 | { 17 | std::cout << count[i]; 18 | } 19 | 20 | // for (int i = 0; i < 10; i++) 21 | // { 22 | // int n = std::rand() % 100; 23 | // std::cout << n << std::endl; 24 | // } 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Linux/EX_3/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define BUFFER_SIZE 4 11 | #define CONSUMER_NUM 4 12 | #define PRODUCER_NUM 3 13 | 14 | int BUFFER_SHMID = -1; 15 | int POINTER_SHMID = -1; 16 | int SEMID = -1; 17 | //规定信号序列号0是mutex=1,1是full=0,2是empty=BUFFER_SIZE 18 | enum 19 | { 20 | mutex_i, 21 | full_i, 22 | empty_i 23 | }; 24 | 25 | using namespace std; 26 | 27 | void PrintBuffer(char *buffer_addr) 28 | { 29 | for (int i = 0; i < BUFFER_SIZE; i++) 30 | { 31 | cout << buffer_addr[i]; 32 | } 33 | cout << endl; 34 | } 35 | 36 | int CreateProcess(const char *processPath) 37 | { 38 | pid_t pid = vfork(); 39 | if (pid == 0) 40 | { 41 | execl(processPath, to_string(BUFFER_SHMID).c_str(), to_string(POINTER_SHMID).c_str(), to_string(SEMID).c_str(), NULL); 42 | } 43 | else if (pid == -1) 44 | { 45 | perror("Create Process Failed\n"); 46 | exit(EXIT_FAILURE); 47 | } 48 | return 0; 49 | } 50 | int main(int argc, char const *argv[]) 51 | { 52 | //申请共享内存区 53 | BUFFER_SHMID = shmget(IPC_PRIVATE, BUFFER_SIZE, IPC_CREAT | IPC_EXCL); 54 | memset(shmat(BUFFER_SHMID, NULL, 0), '/', BUFFER_SIZE); 55 | 56 | //申请队列指针 57 | POINTER_SHMID = shmget(IPC_PRIVATE, sizeof(int) * 2, IPC_CREAT | IPC_EXCL); 58 | //初始化队列指针 59 | int *pt = (int *)shmat(POINTER_SHMID, NULL, 0); 60 | *pt = 0; 61 | *(pt + 1) = 0; //第一个指针供消费者使用,第二个指针供生产者使用 62 | 63 | //初始化信号量 64 | SEMID = semget(IPC_PRIVATE, 3, IPC_CREAT | IPC_EXCL); 65 | 66 | //给资源量初始化 67 | semctl(SEMID, mutex_i, SETVAL, 1); 68 | semctl(SEMID, full_i, SETVAL, 0); 69 | semctl(SEMID, empty_i, SETVAL, BUFFER_SIZE); 70 | 71 | //只要有一个步骤没成功,这个实验就不用做了 72 | if (BUFFER_SHMID == -1 || POINTER_SHMID == -1 || SEMID == -1) 73 | { 74 | perror("Request IPC Failed\n"); 75 | exit(EXIT_FAILURE); 76 | } 77 | 78 | //创建消费者 79 | for (int i = 0; i < 4; i++) 80 | { 81 | CreateProcess("Consumer.out"); 82 | } 83 | 84 | //创建生产者 85 | for (int i = 0; i < 3; i++) 86 | { 87 | CreateProcess("Producer.out"); 88 | } 89 | 90 | int status; 91 | //因为一共创建了7个子进程,所以要等7下 92 | for (int i = 0; i < 7; i++) 93 | { 94 | wait(&status); 95 | } 96 | 97 | //程序结束,回收资源 98 | cout << "Simulation end" << endl; 99 | shmctl(BUFFER_SHMID, IPC_RMID, NULL); 100 | shmctl(POINTER_SHMID, IPC_RMID, NULL); 101 | semctl(SEMID, 0, IPC_RMID); 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /Linux/EX_3/posix.b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Linux/EX_3/posix.b -------------------------------------------------------------------------------- /Linux/EX_4/README.md: -------------------------------------------------------------------------------- 1 | 实验4的Linux版是只用展示命令行操作? 2 | 3 | 用top命令查看系统,子命令P、T、M 4 | 5 | 用ps -A查看所有进程,找到ProcessParent的pid 6 | 7 | 用top -p pid查看ProcessParent程序的情况; 8 | 9 | 用pmap -d pid查看ProcessParent的内存使用情况 10 | 11 | 12 | # Top 13 | 14 | `top`命令有外置的和内置的两种。如果需要输入内置命令,在终端直接输入`top`进去界面后,再输入对应命令,`top`的内置命令通常都是交互性的。而外置命令则需通过shell解释器传递,并且一般是不能交互的,比如`top -n 10` 15 | 16 | ## 内置命令 17 | ### s或者d:改变刷新时间 18 | 终端输入`top`进入界面后,接着按下`d`,在界面的上部会出现一个可供你输入的地方,并提示你: 19 | 20 | ``` 21 | Change delay from 3.0 to 22 | ``` 23 | 24 | `top`默认的刷新时间是3秒,你现在就可以输入新的秒来改变top的刷新时间了。注意,可以输入小于1的值,比如可以输入`0.1`之类的加快刷新速度。 25 | 26 | ### 课程要求的三命令:P、T、M 27 | 这里有个地方要注意,当你输入这三个子命令时,要确保你的键盘开着大写模式。否则输入`p`\\`t`\\`m`的话,`top`是看不懂的 28 | 29 | 功能如下: 30 | + P:以CPU占用率的大小顺序排列进程表(默认进入top时就是P模式) 31 | + T:根据进程运行时间排序 32 | + M:按内存占用率的大小排序 33 | 34 | ## 外置命令 35 | 这个是直接在shell中输入的 36 | ### -p 37 | ```shell 38 | top -p 39 | ``` 40 | 这个可以将某个进程id为``的进程单独拎出来看 41 | 42 | 比如输入: 43 | 44 | `top -p 1` 45 | 46 | 就可以持续查看1号进程`init`的信息了 47 | 48 | # ps 49 | ## 找到需要的进程的pid 50 | 我会使用 51 | `ps -A | grep 'parentProcess'` 52 | 53 | 来找到对应进程名的id 54 | 55 | # pmap 56 | `pmap -d`: 57 | + Address 58 | + 内存开始地址 59 | 60 | + Kbytes 61 | + 占用内存的字节数 62 | 63 | + Mode 64 | + 内存的权限 65 | 66 | + offset 67 | + 文件偏移 68 | 69 | + Mapping 70 | + 占用的种类 71 | + 占用内存的文件 72 | + anon:分配的内存 73 | + stack:栈 -------------------------------------------------------------------------------- /Linux/EX_5/README.md: -------------------------------------------------------------------------------- 1 | **myCp这题还蛮坑的** 2 | 3 | 想写出健壮的myCp并不容易。尤其是在读目录和递归一块,很容易读到`.`导致递归失败。因此错误返回值判断很重要! 4 | 5 | 为了移动符号链接本身,应该使用`lstat`而不是`fstat`。 6 | 7 | 另外就是保证时间戳保持原样的时间戳修改,符号链接类型的时间戳修改函数需要也添加额外的flag。 8 | 9 | 没错,这些东西不看Linux的`man`手册是无法弄明白的。 10 | 11 | 测试myCp可以试试`./myCp.out /etc .`。 12 | 13 | 如果能把整个庞大的、文件类型丰富的`/etc`文件夹都能搬过来,则能表明通过测试。 -------------------------------------------------------------------------------- /Linux/EX_5/Test/SwitchType.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | //todo:找到建立新路径的方法 10 | void SwitchType(const char *path); 11 | 12 | void OpDir(const char *path) 13 | { 14 | DIR *dir = opendir(path); 15 | cout << "content in " << path << ":" << endl; 16 | while (true) 17 | { 18 | dirent *d = readdir(dir); 19 | //在dest的什么地方新建文件夹? 20 | if (d != 0) 21 | { 22 | if (strncmp(d->d_name, "..", 200) == 0) 23 | { 24 | break; 25 | } 26 | cout << d->d_name << endl; 27 | char *new_path = (char *)calloc((strlen(path) + strlen(d->d_name)) + 4, sizeof(char)); 28 | strncpy(new_path, path, strlen(path)); 29 | strcat(new_path, "/"); 30 | strncat(new_path, d->d_name, strlen(d->d_name)); 31 | cout << "new_path:" << new_path << endl; //递归成功 32 | SwitchType(new_path); 33 | free(new_path); 34 | } 35 | else 36 | { 37 | break; 38 | } 39 | } 40 | cout << "------------------" << endl; 41 | } 42 | //可能的类型:文件夹、文件、软链接 43 | void SwitchType(const char *path) 44 | { 45 | struct stat a; 46 | stat(path, &a); 47 | if (S_ISDIR(a.st_mode)) 48 | { 49 | cout << "This is a directory" << endl; 50 | // cout << a.st_mode << endl; 51 | cout << a.st_mode << endl; 52 | //先建一个文件夹? 53 | OpDir(path); 54 | } 55 | } 56 | int main(int argc, char const *argv[]) 57 | { 58 | if (argc >= 2) 59 | { 60 | SwitchType(argv[1]); 61 | } 62 | // getcwd 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Linux/EX_5/Test/my_MKdir.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Linux/EX_5/Test/my_MKdir.cpp -------------------------------------------------------------------------------- /Linux/EX_5/Test/softLinkTime.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | void MoveFile(const char *path, const char *dest_path); 12 | int main(int argc, char const *argv[]) 13 | { 14 | if (argc >= 2) 15 | { 16 | //argv 1是源文件,argv 2是目标路径 17 | // MoveFile(argv[1], argv[2]); 18 | struct stat st; 19 | lstat(argv[1], &st); 20 | timespec tspc[2]; 21 | char *new_dest = (char *)calloc(MAX_INPUT * 4, sizeof(char)); 22 | tspc[0].tv_nsec = UTIME_NOW; 23 | tspc[1].tv_nsec = UTIME_NOW; 24 | utimensat(AT_FDCWD, argv[1], tspc, AT_SYMLINK_NOFOLLOW); 25 | } 26 | // else 27 | // { 28 | // cout << "Too little argument!" << endl; 29 | // } 30 | 31 | return 0; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /Linux/EX_5/myCp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #define MAX_PATH_LENGTH 100 11 | using namespace std; 12 | int MoveFile(const char *path, const char *dest_path); 13 | int main(int argc, char const *argv[]) 14 | { 15 | if (argc >= 3) 16 | { 17 | //argv 1是源文件,argv 2是目标路径 18 | MoveFile(argv[1], argv[2]); 19 | } 20 | else 21 | { 22 | cout << "Too little argument!" << endl; 23 | } 24 | 25 | return 0; 26 | } 27 | int MoveFile(const char *path, const char *dest_path) 28 | { 29 | struct stat st; 30 | lstat(path, &st); //为了打开链接文件本身,使用lstat 31 | const char *file_name = basename(path); 32 | char *new_dest = (char *)calloc(MAX_PATH_LENGTH, sizeof(char)); //new_dest是文件要移动到的目录 33 | if (new_dest == NULL || file_name == NULL) 34 | { 35 | perror("string alloc failed\n"); 36 | return -1; 37 | } 38 | 39 | strncpy(new_dest, dest_path, MAX_PATH_LENGTH / 2); 40 | strncat(new_dest, "/", 1); 41 | strncat(new_dest, file_name, MAX_PATH_LENGTH / 2); 42 | 43 | //目录操作 44 | if (S_ISDIR(st.st_mode)) 45 | { 46 | //在目标新建一个地址 47 | mkdir(new_dest, st.st_mode); 48 | //对目录里面的文件递归调用MoveFile 49 | DIR *dir = opendir(path); //这个目录很可能打不开 50 | char *recursive_path = (char *)calloc(MAX_PATH_LENGTH, sizeof(char)); //recursive_path用于二级文件等的递归调用 51 | if (recursive_path == NULL) 52 | { 53 | perror("string alloc failed\n"); 54 | return -1; 55 | } 56 | if (dir == NULL) //目录没打开 57 | { 58 | cout << "open" << path << "failed" << endl; 59 | return -1; 60 | } 61 | 62 | while (true) 63 | { 64 | dirent *d = readdir(dir); 65 | //d是游标,用来获取文件名 66 | if (d != 0) 67 | { 68 | //读到..和.的意思是读到了当前文件夹,我们不需要也无法移动它们 69 | if (strncmp(d->d_name, "..", 3) == 0 || strncmp(d->d_name, ".", 2) == 0) 70 | { 71 | continue; 72 | } 73 | strncpy(recursive_path, path, MAX_PATH_LENGTH / 2); 74 | strncat(recursive_path, "/", 1); 75 | strncat(recursive_path, d->d_name, MAX_PATH_LENGTH / 2); 76 | //对文件夹中的文件操作 77 | if (MoveFile(recursive_path, new_dest) == -1) 78 | { 79 | cout << "move file from " << recursive_path << "to" << new_dest << "failed" << endl; 80 | } 81 | memset(recursive_path, 0, MAX_PATH_LENGTH); 82 | } 83 | else 84 | { 85 | break; 86 | } 87 | } 88 | free(recursive_path); 89 | } 90 | //软链接操作 待测试 91 | else if (S_ISLNK(st.st_mode)) 92 | { 93 | char *linked_path = (char *)calloc(MAX_PATH_LENGTH, sizeof(char)); 94 | if (linked_path == NULL) 95 | { 96 | perror("string alloc failed\n"); 97 | return -1; 98 | } 99 | 100 | readlink(path, linked_path, MAX_PATH_LENGTH); 101 | symlink(linked_path, new_dest); 102 | free(linked_path); 103 | } 104 | //普通文件 105 | else if (S_ISREG(st.st_mode)) 106 | { 107 | creat(new_dest, st.st_mode); 108 | int file_old = open(path, O_RDONLY); 109 | int file_new = open(new_dest, O_WRONLY); 110 | int bt_read = 0; 111 | char buffer[MAX_PATH_LENGTH]; 112 | while (true) 113 | { 114 | bt_read = read(file_old, buffer, MAX_PATH_LENGTH); 115 | write(file_new, buffer, bt_read); 116 | if (bt_read == 0) 117 | { 118 | break; 119 | } 120 | } 121 | close(file_old); 122 | close(file_new); 123 | } 124 | //修改时间戳 125 | timespec tspc[2]; 126 | tspc[0] = st.st_atim; 127 | tspc[1] = st.st_mtim; 128 | if (S_ISLNK(st.st_mode)) 129 | { 130 | utimensat(AT_FDCWD, new_dest, tspc, AT_SYMLINK_NOFOLLOW); //根据文档,后面这个AT_SYMLINK_NOFOLLOW的flag开启后符号链接的时间戳才能改变(而不是改变指向文件的) 131 | } 132 | else 133 | { 134 | utimensat(AT_FDCWD, new_dest, tspc, 0); //根据文档,后面这个AT_SYMLINK_NOFOLLOW的flag开启后符号链接的时间戳才能改变(而不是改变指向文件的) 135 | } 136 | 137 | free(new_dest); 138 | return 0; 139 | } -------------------------------------------------------------------------------- /Linux/README.md: -------------------------------------------------------------------------------- 1 | * 实验一: 编译内核 2 | * 实验二(EX_2):启动进程`start process` 3 | * 实验三(EX_3):生产者消费者 4 | * 实验四(EX_4):实现进程资源查看器 5 | * 实验五(EX_5):实现递归移动整个文件夹的`myCp` 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BIT-OSD 2 | 北京理工大学操作系统课程设计的代码 3 | 4 | # 实验内容 5 | 不同操作系统的实验放在了`Linux`和`Windows`的`EX_*`文件夹中 6 | * 实验一: 编译内核 7 | * 实验二(EX_2):启动进程`start process` 8 | * 实验三(EX_3):生产者消费者 9 | * 实验四(EX_4):实现进程资源查看器 10 | * 实验五(EX_5):实现递归移动整个文件夹的`myCp` 11 | 12 | # 环境 13 | ## Windows 14 | ~~Visual Studio2019;控制台子系统;MSVC编译~~ 15 | * ~~实验一:WZC专属的实验一,通过Visual Studio编译了NT内核~~ 16 | * 实验二:Visual Studio 17 | * 实验三:vscode + mingw-w64;编写完毕后在Visual Studio中进行语义检查。 18 | * 实验四:Visual Studio 19 | * 实验五:Visual Studio 20 | 21 | 22 | ## Linux 23 | WSL2中使用g++编译,gdb调试 24 | 25 | # 编程指北 26 | 调用曾经从未用过的系统API是一件非常有挑战性的事情。许多函数接口需要输入的参数难以一眼就分辨出来(尤其是Win32 API)。 27 | ## Windows 28 | 推荐直接在MSDN上查看Win32 Api的一手资料。https://docs.microsoft.com/en-us/windows/win32/api/ 29 | 30 | 建议的路线是:查看老师的PPT课件后,知道本次设计需要利用到哪些函数,接着再到MSDN处查对应函数的接口。 31 | 32 | > 教学PPT找到函数名->在MSDN的搜索框里粘贴函数名->查看对应的编程手册->仔细查看函数接口的重要部分(比如需要设置数值的、需要传入字符串的),稍微忽略一些不重要部分,并提醒自己用的时候稍后再看(比如各种flag) 33 | 34 | 虽然Win32的API文档是全英文的可能会有点劝退,但英语语法很基本,用心看是能看懂的,更何况还有谷歌翻译的力量。另一方面其实文档真正需要看的地方并不多,一些函数传入的flag快速扫一遍即可,因为它们大多通过变量名就能看出用途。 35 | 36 | 推荐直接看一手文档的根本原因是:微软的文档实在是写的太好了。非常详细,并且关键部分会给你新的链接让你拓展阅读,文档中展示示例代码更是常规操作。假如你能看完,那么课上验收时,无论老师怎么提问都能轻而易举的答出来,并且还会获得许多超越课本的知识涉猎与感悟。文档的很多地方是可以和操作系统理论课的Windows部分的知识串起来的。粗读ppt+精读msdn,大体和细节组合连击,是一种非常美妙的体验。 37 | 38 | ### Win32 API 传入参数命名规则 39 | 对于Win32 API,我觉得许多人在最初时都会和我有一样的感觉:Windows的Api传入参数的命名实在是太丑了!! 40 | 41 | 以`CreateProcess`为例,`lpApplicationName`、`bInheritHandles`、`dwCreationFlags`这些传入参数前的`lp`、`b`、`dw`等着实令人很在意[问题1]。 42 | 43 | 除此之外,甚至连传入的变量的类型都令人看不懂,比如`LPCSTR`、`LPSTR`、`DWORD`等[问题2]。 44 | 45 | 事实上,对于[问题1],这个是Windows变量的命名法则:匈牙利命名法。在每个变量名的最前面引入这个变量类型的缩写,可以令程序员瞬间理解应该传入什么类型的变量,大大的减少出错的概率(因为在早期,代码编辑工具的语法检测还没那么强大)。 46 | 47 | 比如,`lp`代表`long pointer`,告诉你要传入一个指针变量(因为曾经Windows是16位的,所以大于16位的指针就相对成为了“long”指针)、`b`则指`Boolean`、`dw`则是`DWord`(什么是DWord等会再说)。再举一个常见的例子:常见的`szXXX`前面的`sz`指的是“以0结尾的字符串”(大概可以理解为"string returns zero"?)。 48 | 49 | 总之,很大程度上通过变量名就可以知道这个函数的参数应该传一个指针(lp,字符串一般也是lp)、一个数(dw)、或者是一个布尔值。特别说明一下,常见的`h`,指的是句柄(`HANDLE`)。 50 | 51 | 匈牙利命名法的详情可见 https://docs.microsoft.com/zh-cn/windows/win32/learnwin32/windows-coding-conventions?redirectedfrom=MSDN 52 | 53 | 对于[问题2],你则可以理解为Windows为了实现无敌的向前向后的史诗级别的兼容性,自己定义了很多变量,并将其映射到原始C语言的类型。比如,我们大一就知道,很多变量类型的大小会随着编译器(以及机器字长)的不同而变得不同(比如int),这样必然会对程序的移植性产生困难:比如原本一个好好的变量,可能换一个编译器运行就运算溢出了。由于有这个情况的存在,微软干脆就自己typedef了一堆变量,使得即使后续系统架构迁移(比如32位迁移到64位、x86迁移到arm),也最多只需要改一下typdef映射的对象,而无需在源代码处一个个修改(比如把`int`手动替换为`long`等)就可以方便程序移植并且不出错。 54 | 55 | *事实上,但凡你在使用Win32 Api的时候感觉到了任何一点的不优雅性,都可以理解这都是Windows拓展性和兼容性上所做出的努力。~~Windows的设计是最优雅的!~~* 56 | 57 | 一些常见的变量类型如下: 58 | | Data type | Size | Signed? | 59 | | :------------ | :------ | :------- | 60 | | **BYTE** | 8 bits | Unsigned | 61 | | **DWORD** | 32 bits | Unsigned | 62 | | **INT32** | 32 bits | Signed | 63 | | **INT64** | 64 bits | Signed | 64 | | **LONG** | 32 bits | Signed | 65 | | **LONGLONG** | 64 bits | Signed | 66 | | **UINT32** | 32 bits | Unsigned | 67 | | **UINT64** | 64 bits | Unsigned | 68 | | **ULONG** | 32 bits | Unsigned | 69 | | **ULONGLONG** | 64 bits | Unsigned | 70 | | **WORD** | 16 bits | Unsigned | 71 | 72 | 比如DWORD是无符号整形,所以Windows内经常把它当各种Flag来用。 73 | 74 | 对于各种字符串的话,上面给出的链接也有说明,它们通常都是各种缩写。比如`LPWSTR`是“Long Pointer of Wide Char(宽字符,正好可以兼容Windows常用的UTF-16编码)”,而`LPCWSTR`表示“Long Pointer of Const Wide Char(比上面一个多了个const。Windows有个潜规则,凡是不带const的变量,你都不要传个const的`"字符串"`进去,Windows通常会对非const的地址的内容进行修改(虽然改完后又会复原))” 75 | 76 | 关于句柄的使用,用户并不用操心~~操心了也没用,我们几乎无法对句柄进行任何操作~~。只用知道句柄的本质是地址,负责链接各种内核需要的对象的数据,我们只负责把句柄传给操作系统,让操作系统决定这个句柄对应的对象该怎么处理,就可以玩的很爽了。(Windows真的优雅!) 77 | 78 | 对了,Windows比Linux优雅的另一个显著的地方在于:一个`#include `可以囊括万物。(除了一些需要用到特定dll的函数,比如实验4) 79 | 80 | 再多提一句,无论是使用VS code,还是Dev C++之类的开源IDE,它们用的编译器都是mingw,其中的win32的API是mingw自行实现的,在许多表现上和微软官方的Visual Studio所使用MSVC编译器有所不同(比如缺少了很多64位的库,LPWSTR是char*而不是wchar_t*,并且L""转化宽字符不能用等)。虽然课程并没有要求,但是如果要使用正统的Win32 Api最好在VS中编写、编译、调试Windows版本的程序!(但是VS实在是太难用了!) 81 | 82 | ## Linux 83 | Linux的编程就很简单了。不仅文档多,接口也很简单。 84 | 85 | POSIX接口虽然在一致性上比较差(比如IPC类型的system V风格对比其他API),但是调用起来都很简单,也很符合直觉。 86 | 87 | 不过我还是建议阅读一手文档。 88 | https://www.kernel.org/doc/man-pages/ 89 | 90 | 相当于Linux世界的MSDN,我们需要的函数都能在其中第二章的 https://man7.org/linux/man-pages/dir_section_2.html 也就是`System Call`中找到。直接`Ctrl`+`F`查找到你要的函数名点进去即可。 91 | 92 | 这个网页的本质等同于Linux命令的`man`,你甚至可以直接在Linux的命令行下输入自己要找的命令,比如`man fork`,就能轻易的找到这个函数所在的头文件、用法、返回值等信息。不过使用网页直接看的话,有个好处是超链接的跳转会很方便。 93 | -------------------------------------------------------------------------------- /Windows/EX_2/ChildProcess.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_2/ChildProcess.cpp -------------------------------------------------------------------------------- /Windows/EX_2/ChildProcess.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_2/ChildProcess.exe -------------------------------------------------------------------------------- /Windows/EX_2/StartProcess.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_2/StartProcess.cpp -------------------------------------------------------------------------------- /Windows/EX_2/StartProcess.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_2/StartProcess.exe -------------------------------------------------------------------------------- /Windows/EX_3/Producer_Consumer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #define BUFFER_SIZE 4 6 | #define PRODUCER_NUM 3 7 | #define CONSUMER_NUM 4 8 | #define SH_MEMORY_NAME "EX3_SHARED_MEMORY" 9 | #define SH_POINTER_NAME "EX3_SHARED_POINTER" 10 | #define SE_EMPTY_NAME "EX3_SHARED_EMPTY" 11 | #define SE_FULL_NAME "EX3_SHARED_FULL" 12 | #define SM_MUTEX_NAME "EX3_SHARED_MUTEX" 13 | 14 | HANDLE hStdout; 15 | CONSOLE_SCREEN_BUFFER_INFO pBuffer; 16 | 17 | #define PRINT_DELAY_TIME 70 //为了让打印动画更好看 18 | 19 | using namespace std; 20 | char const **ARGV; 21 | int ARGC; 22 | enum 23 | { 24 | PARENT_PROCESS, 25 | PRODUCER_PROCESS, 26 | CONSUMER_PROCESS 27 | } START_PROCESS_TOKENS; 28 | 29 | int main_parent(); 30 | int main_consumer(); 31 | int main_producer(); 32 | int (*switch_main[3])(void) = {main_parent, main_producer, main_consumer}; //静态编译性能高 33 | 34 | int main(int argc, char const *argv[]) 35 | { 36 | int swich_token = argc; 37 | ARGV = argv; 38 | ARGC = argc; 39 | //得到控制台当前光标坐标 40 | if (swich_token <= 1) 41 | { 42 | //直接不带参数启动则是父进程 43 | swich_token = PARENT_PROCESS; 44 | } 45 | else 46 | { 47 | //其余的都根据自己令牌启动 48 | swich_token = atol(argv[1]); 49 | if (swich_token > CONSUMER_PROCESS) 50 | { 51 | exit(EXIT_FAILURE); 52 | } 53 | } 54 | //这样比switch case性能高 55 | return switch_main[swich_token](); 56 | } 57 | 58 | void PrintBuffer(char *buffer_addr) //打印缓冲区内容 59 | { 60 | cout << buffer_addr << endl; 61 | } 62 | 63 | //改变打印终端的指针,实现原地打印 64 | void ResetCursor(CONSOLE_SCREEN_BUFFER_INFO pBuffer) 65 | { 66 | 67 | CONSOLE_CURSOR_INFO console_cursor_info; 68 | console_cursor_info.bVisible = false; 69 | console_cursor_info.dwSize = 100; 70 | HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); 71 | SetConsoleCursorInfo(hConsole, &console_cursor_info); 72 | COORD coordScreen = {pBuffer.dwCursorPosition.X, pBuffer.dwCursorPosition.Y}; 73 | SetConsoleCursorPosition(hConsole, coordScreen); 74 | } 75 | //程序开始前先清理一下终端,让打印出的字符更好看 76 | void ClearConsole() 77 | { 78 | COORD topLeft = {0, 0}; 79 | HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); 80 | CONSOLE_SCREEN_BUFFER_INFO screen; 81 | DWORD written; 82 | 83 | GetConsoleScreenBufferInfo(console, &screen); 84 | FillConsoleOutputCharacterA( 85 | console, ' ', screen.dwSize.X * screen.dwSize.Y, topLeft, &written); 86 | FillConsoleOutputAttribute( 87 | console, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE, 88 | screen.dwSize.X * screen.dwSize.Y, topLeft, &written); 89 | SetConsoleCursorPosition(console, topLeft); 90 | } 91 | 92 | PROCESS_INFORMATION CreateChildProcess(int process_token) 93 | { 94 | STARTUPINFO si; 95 | ZeroMemory(&si, sizeof(si)); 96 | PROCESS_INFORMATION pi; 97 | ZeroMemory(&pi, sizeof(pi)); 98 | 99 | char c_cmd[100] = {0}; 100 | char cd[1000] = {0}; //MSVC中要改成wchar 101 | GetCurrentDirectory(1000, cd); 102 | sprintf_s(c_cmd, 100, "%ld %d", GetCurrentProcessId(), process_token); 103 | 104 | CreateProcess(TEXT(ARGV[0]), TEXT(c_cmd), NULL, NULL, TRUE, 0, NULL, cd, &si, &pi); 105 | return pi; 106 | } 107 | 108 | int main_parent() 109 | { 110 | //初始化 111 | //创建共享内存 112 | HANDLE h_FM = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, BUFFER_SIZE, SH_MEMORY_NAME); 113 | //队列指针也是共享的,第一个给消费者用,第二个给生产者用 114 | HANDLE h_P = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, sizeof(int) * 2, SH_POINTER_NAME); 115 | 116 | if (h_FM == NULL || h_P == NULL) 117 | { 118 | perror("PARTENT IPC HANDEL ERROR"); 119 | exit(EXIT_FAILURE); 120 | } 121 | 122 | char *buffer_addr = (char *)MapViewOfFile(h_FM, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE); 123 | int *pointer_addr = (int *)MapViewOfFile(h_P, FILE_MAP_ALL_ACCESS, 0, 0, (sizeof(int) * 2)); 124 | 125 | if (buffer_addr == 0 || pointer_addr == 0) 126 | { 127 | perror("PARENT MEMORY ALLOC FAILED"); 128 | exit(EXIT_FAILURE); 129 | } 130 | memset(buffer_addr, '/', BUFFER_SIZE); 131 | pointer_addr[0] = 0; 132 | pointer_addr[1] = 0; 133 | 134 | //申请信号量和mutex 135 | HANDLE h_sFull = CreateSemaphore(NULL, 0, BUFFER_SIZE, SE_FULL_NAME); 136 | HANDLE h_sEmpty = CreateSemaphore(NULL, BUFFER_SIZE, BUFFER_SIZE, SE_EMPTY_NAME); 137 | 138 | //HANDLE h_mMutex = CreateSemaphore(NULL, 1, 1, SM_MUTEX_NAME); 139 | HANDLE h_mMutex = CreateMutex(NULL, FALSE, SM_MUTEX_NAME); 140 | 141 | ClearConsole(); //先清一下屏 142 | hStdout = GetStdHandle(STD_OUTPUT_HANDLE); //得到控制台当前光标坐标 143 | ClearConsole(); //先清一下屏 144 | 145 | //4个消费者,3个生产者 146 | HANDLE h_Processes[CONSUMER_NUM + PRODUCER_NUM]; 147 | for (int i = 0; i < CONSUMER_NUM; i++) 148 | { 149 | h_Processes[i] = (CreateChildProcess(CONSUMER_PROCESS)).hProcess; 150 | } 151 | for (int i = CONSUMER_NUM; i < CONSUMER_NUM + PRODUCER_NUM; i++) 152 | { 153 | h_Processes[i] = (CreateChildProcess(PRODUCER_PROCESS)).hProcess; 154 | } 155 | WaitForMultipleObjects(CONSUMER_NUM + PRODUCER_NUM, h_Processes, true, INFINITE); 156 | 157 | return 0; 158 | } 159 | 160 | int main_consumer() 161 | { 162 | //共享地址、信号量初始化 163 | HANDLE h_FM = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, SH_MEMORY_NAME); 164 | HANDLE h_P = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, SH_POINTER_NAME); 165 | 166 | char *buffer_addr = (char *)MapViewOfFile(h_FM, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE); 167 | int *pointer_addr = (int *)MapViewOfFile(h_P, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(int)); 168 | 169 | if (buffer_addr == 0 || pointer_addr == 0) 170 | { 171 | perror("CONSUMER MEMORY ALLOC FAILED"); 172 | exit(EXIT_FAILURE); 173 | } 174 | 175 | HANDLE h_sFull = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, SE_FULL_NAME); 176 | HANDLE h_sEmpty = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, SE_EMPTY_NAME); 177 | //HANDLE h_mMutex = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, SM_MUTEX_NAME); 178 | HANDLE h_mMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, SM_MUTEX_NAME); 179 | 180 | if (h_sFull == NULL || h_sEmpty == NULL || h_mMutex == NULL) 181 | { 182 | perror("IPC Handle Error"); 183 | exit(EXIT_FAILURE); 184 | } 185 | 186 | //开始循环 187 | for (int i = 0; i < 3; i++) 188 | { 189 | GetConsoleScreenBufferInfo(hStdout, &pBuffer); 190 | srand(GetTickCount()); 191 | Sleep((rand() % 4) * 1000); 192 | //申请一个full 193 | WaitForSingleObject(h_sFull, INFINITE); 194 | //申请进入缓冲区 195 | WaitForSingleObject(h_mMutex, INFINITE); 196 | ResetCursor(pBuffer); 197 | Sleep(PRINT_DELAY_TIME * 10); 198 | 199 | //取数,改指针 200 | cout << "A Consumer joined!" << endl; 201 | // PrintBuffer(buffer_addr); 202 | Sleep(PRINT_DELAY_TIME); 203 | cout << "get:" << buffer_addr[*pointer_addr] << endl; 204 | buffer_addr[*pointer_addr] = '/'; 205 | *pointer_addr = (*pointer_addr + 1) % BUFFER_SIZE; 206 | 207 | Sleep(PRINT_DELAY_TIME); 208 | PrintBuffer(buffer_addr); 209 | 210 | //释放一个empty 211 | ReleaseSemaphore(h_sEmpty, 1, NULL); 212 | //退出缓冲区 213 | //ReleaseSemaphore(h_mMutex, 1, NULL); 214 | ReleaseMutex(h_mMutex); 215 | } 216 | CloseHandle(h_mMutex); 217 | CloseHandle(h_sEmpty); 218 | CloseHandle(h_sFull); 219 | CloseHandle(h_FM); 220 | return 0; 221 | } 222 | 223 | int main_producer() 224 | { 225 | 226 | HANDLE h_FM = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, SH_MEMORY_NAME); 227 | HANDLE h_P = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, SH_POINTER_NAME); 228 | 229 | char *buffer_addr = (char *)MapViewOfFile(h_FM, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE); 230 | int *pointer_addr = (int *)MapViewOfFile(h_P, FILE_MAP_ALL_ACCESS, 0, 0, (sizeof(int) * 2)); 231 | 232 | if (buffer_addr == 0 || pointer_addr == 0) 233 | { 234 | perror("PRODUCER MEMORY ALLOC FAILED"); 235 | exit(EXIT_FAILURE); 236 | } 237 | 238 | pointer_addr += 1; 239 | HANDLE h_sFull = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, SE_FULL_NAME); 240 | HANDLE h_sEmpty = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, SE_EMPTY_NAME); 241 | //HANDLE h_mMutex = OpenSemaphore(SEMAPHORE_ALL_ACCESS, TRUE, SM_MUTEX_NAME); 242 | HANDLE h_mMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, SM_MUTEX_NAME); 243 | if (h_sFull == NULL || h_sEmpty == NULL || h_mMutex == NULL) 244 | { 245 | perror("IPC Handle Error"); 246 | exit(EXIT_FAILURE); 247 | } 248 | const char *WZC = "WZC"; 249 | 250 | //开始循环 251 | for (int i = 0; i < 4; i++) 252 | { 253 | GetConsoleScreenBufferInfo(hStdout, &pBuffer); //得到控制台光标坐标 254 | 255 | srand(GetTickCount()); //改变随机数种子 256 | Sleep((rand() % 3) * 1000); //随机睡眠 257 | 258 | //申请一个empty 259 | WaitForSingleObject(h_sEmpty, INFINITE); 260 | //申请进入缓冲区 261 | WaitForSingleObject(h_mMutex, INFINITE); 262 | ResetCursor(pBuffer); 263 | Sleep(PRINT_DELAY_TIME * 10); 264 | 265 | //取数,改指针 266 | cout << "A Producer joined!" << endl; 267 | // PrintBuffer(buffer_addr); 268 | int put_index = rand() % 3; 269 | Sleep(PRINT_DELAY_TIME); 270 | cout << "put:" << WZC[put_index] << endl; 271 | buffer_addr[*pointer_addr] = WZC[put_index]; 272 | *pointer_addr = (*pointer_addr + 1) % BUFFER_SIZE; 273 | Sleep(PRINT_DELAY_TIME); 274 | PrintBuffer(buffer_addr); 275 | 276 | //释放一个Full 277 | ReleaseSemaphore(h_sFull, 1, NULL); 278 | //退出缓冲区 279 | ReleaseMutex(h_mMutex); 280 | //ReleaseSemaphore(h_mMutex, 1, NULL); 281 | } 282 | CloseHandle(h_mMutex); 283 | CloseHandle(h_sEmpty); 284 | CloseHandle(h_sFull); 285 | CloseHandle(h_FM); 286 | return 0; 287 | } 288 | -------------------------------------------------------------------------------- /Windows/EX_3/Producer_Consumer.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_3/Producer_Consumer.exe -------------------------------------------------------------------------------- /Windows/EX_3/Producer_Consumer_20.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_3/Producer_Consumer_20.exe -------------------------------------------------------------------------------- /Windows/EX_3/README.md: -------------------------------------------------------------------------------- 1 | > 本实验的Windows版本通过实现一个文件产生8个进程(生产者+消费者+一个主进程)来模拟生产者消费者,在main函数中实现不同进程的主函数切换,并且实现了原地终端打印,方便观看。 2 | 3 | *为什么Producer和Consumer的函数看起来那么冗余呢?* 4 | 5 | 因为原本它们应该处于不同的文件的不同main中,所以它们本来应该就是相似的。这样写方便即使后续有必要,这个文件也能单独拆出来。 6 | 7 | *为什么只用一个执行文件而不是三个执行文件呢* 8 | 9 | 因为Visual Studio难以同时编译三个带有main的函数并且同时运行。 -------------------------------------------------------------------------------- /Windows/EX_3/Test/Sema.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | #define SEMANAME "Shared_Sema" 6 | void child() 7 | { 8 | cout << "child process" << endl; 9 | for (int i = 0; i < 4; i++) 10 | { 11 | HANDLE hS = OpenSemaphore(SEMAPHORE_MODIFY_STATE, false, SEMANAME); 12 | cout << "I joined in!" << endl; 13 | ReleaseSemaphore(hS, NULL, NULL); 14 | cout << "\n" 15 | << endl; 16 | Sleep(500); 17 | } 18 | } 19 | void parent() 20 | { 21 | HANDLE hS = CreateSemaphore(NULL, 3, 4, SEMANAME); //因为释放可能会增加多个sema 22 | cout << "parent process" << endl; 23 | } 24 | int main(int argc, char const *argv[]) 25 | { 26 | if (argc == 1) 27 | { 28 | STARTUPINFO si; 29 | ZeroMemory(&si, sizeof(si)); 30 | si.lpTitle = &(string("SemaChild")[0]); 31 | PROCESS_INFORMATION pi; //其实pi可以不初始化,但是由于si装了和新进程有关的消息,所以一定要初始化 32 | HANDLE hC[5]; 33 | for (int i = 0; i < 3; i++) 34 | { 35 | CreateProcess(TEXT(argv[0]), "1 1", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); 36 | hC[i] = pi.hProcess; 37 | } 38 | 39 | parent(); 40 | WaitForMultipleObjects(3,hC,true,INFINITE); 41 | } 42 | else 43 | { 44 | child(); 45 | } 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /Windows/EX_3/Test/Sema.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_3/Test/Sema.exe -------------------------------------------------------------------------------- /Windows/EX_3/Test/currentHandle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | int arg1() 5 | { 6 | printf("hello\n"); 7 | return 0; 8 | } 9 | 10 | int main(int argc, char const *argv[]) 11 | { 12 | HANDLE h; 13 | h = GetCurrentProcess(); 14 | STARTUPINFO si; 15 | PROCESS_INFORMATION pi; 16 | ZeroMemory(&si, sizeof(si)); 17 | si.cb = sizeof(si); 18 | ZeroMemory(&pi, sizeof(pi)); 19 | if (argc == 1) 20 | { 21 | 22 | CreateProcessA("currentHandle.exe", "2 2", NULL, NULL, WINBOOL(false), NULL, NULL, NULL, &si, &pi); //这一句的命令行参数应该传入char*而不是const char* 23 | printf("hello seriously i'm farther\n"); 24 | // WaitForSingleObject(pi.hProcess, INFINITE); //windows是可以等待任何对象结束?并且也设计了最大时长? 25 | // CloseHandle(pi.hProcess); 26 | // CloseHandle(pi.hThread); 27 | Sleep(1000); 28 | } 29 | else 30 | { 31 | WaitForSingleObject(h, 50); //由于通过getcurrentprocess得到的句柄是虚句柄(pseudo handle),因此等的不是父进程?这一句相当于是sleep 32 | arg1(); 33 | printf("Child process wakeup!\n"); 34 | HANDLE ph = OpenProcess(READ_CONTROL, FALSE, pi.dwProcessId); //这个才是真正的父进程 35 | WaitForSingleObject(ph, INFINITE); 36 | printf("this must after the father?\n"); 37 | CloseHandle(GetCurrentProcess()); 38 | } 39 | // std::cout << GetPriorityClass(h); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Windows/EX_3/Test/currentHandle.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_3/Test/currentHandle.exe -------------------------------------------------------------------------------- /Windows/EX_3/Test/sharedMemory.cpp: -------------------------------------------------------------------------------- 1 | //virtualAlloc:分配 2 | //virtualFree:释放 3 | //virtualQuery:查询 4 | #include 5 | #include 6 | #include 7 | #define CHILD 666 //子进程的特殊标识符 8 | #define BUFFERNAME "Shared_Buffer2" 9 | #define MUTEXNAME "Shared_Mutex" 10 | using namespace std; 11 | 12 | void ParentMain(PROCESS_INFORMATION child_info) 13 | { 14 | //做父进程该干的事 15 | HANDLE hM = OpenMutex(MUTEX_MODIFY_STATE, true, MUTEXNAME); //把子进程阻塞 16 | HANDLE hFM = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, 40, BUFFERNAME); //高地址为0,这里使用高32位和低32位应该是为了方便早期32位机映射大文件 17 | char *BufferAddr = (char *)MapViewOfFile(hFM, FILE_MAP_ALL_ACCESS, 0, 0, 40); 18 | 19 | strcpy(BufferAddr, "hello my child! -- from father"); 20 | ReleaseMutex(hM); 21 | 22 | cout << BufferAddr; 23 | WaitForSingleObject(child_info.hProcess, INFINITE); 24 | } 25 | 26 | void ChildMain(DWORD parentId) 27 | { 28 | //通过传给父进程ID的方法来打开父进程 29 | cout << "I'm child,parent id:" << parentId << endl; 30 | HANDLE pp = OpenProcess(PROCESS_ALL_ACCESS, true, parentId); 31 | 32 | HANDLE hM = OpenMutex(MUTEX_MODIFY_STATE, true, MUTEXNAME); 33 | cout << "I wakeup" << endl; 34 | HANDLE hFM = OpenFileMappingA(FILE_MAP_ALL_ACCESS, true, BUFFERNAME); //注意!这里的权限不是PAGE_EXECUTE_READWRITE等的内存页系列权限,而是FILE_MAP系列的权限! 35 | cout << hFM << endl; 36 | 37 | char *BufferAddr = (char *)MapViewOfFile(hFM, FILE_MAP_ALL_ACCESS, 0, 0, 20); 38 | cout << BufferAddr; 39 | cout << "\nI output buffer" << endl; 40 | ReleaseMutex(hM); 41 | } 42 | 43 | int main(int argc, char const *argv[]) 44 | { 45 | cout << "my pid:" << GetCurrentProcessId() << endl; 46 | if (argc == 1 || atoi(argv[1]) != CHILD) 47 | { 48 | //父进程 49 | 50 | PROCESS_INFORMATION pi; //用前一定要zeromemory 51 | STARTUPINFO si; //用前一定要zeromemory 52 | ZeroMemory(&pi, sizeof(pi)); 53 | ZeroMemory(&si, sizeof(si)); 54 | 55 | std::stringstream sscmd; //用sstream优雅的创建命令行参数 56 | sscmd << GetCurrentProcessId() << ' ' << CHILD; //把父进程id、子进程标号打入命令行 57 | 58 | string cmd = sscmd.str(); 59 | cout << cmd << endl; 60 | 61 | CreateProcess(TEXT(argv[0]), TEXT(&(cmd[0])), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); 62 | ParentMain(pi); 63 | CreateMutex(NULL, true, MUTEXNAME); 64 | CloseHandle(pi.hProcess); 65 | CloseHandle(pi.hThread); //closehandle后那个对象还在,只是没有人可以它了引用它了 66 | } 67 | else if (atoi(argv[1]) == CHILD) 68 | { 69 | ChildMain(atol(argv[0])); 70 | } 71 | 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /Windows/EX_3/Test/sharedMemory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_3/Test/sharedMemory.exe -------------------------------------------------------------------------------- /Windows/EX_3/out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_3/out -------------------------------------------------------------------------------- /Windows/EX_3/out.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_3/out.txt -------------------------------------------------------------------------------- /Windows/EX_4/Ex4_Arm.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_4/Ex4_Arm.exe -------------------------------------------------------------------------------- /Windows/EX_4/Ex4_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_4/Ex4_x64.exe -------------------------------------------------------------------------------- /Windows/EX_4/Ex4_x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_4/Ex4_x86.exe -------------------------------------------------------------------------------- /Windows/EX_4/ProcessShot.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_4/ProcessShot.cpp -------------------------------------------------------------------------------- /Windows/EX_4/ProcessShot.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_4/ProcessShot.exe -------------------------------------------------------------------------------- /Windows/EX_4/README.md: -------------------------------------------------------------------------------- 1 | 这个实验有不属于Windows.h的win32 api 2 | 3 | 程序步骤写在了源文件注释中 4 | 5 | ~~MSVC编译优化不能开O2,开了O2后会拍快照失败~~ 6 | 7 | 事实是,PROCESSENTRY32在传入前**还需要一次初始化** 8 | 9 | 使用`now_process.dwSize = sizeof(PROCESSENTRY32)`后,`Process32First()`才能正常工作,否则可能出现奇怪的Bug 10 | 11 | ``` 12 | PROCESSENTRY32 now_process; 13 | 14 | now_process.dwSize = sizeof(PROCESSENTRY32); 15 | 16 | if (!Process32First(hProcessesShot, &now_process)) 17 | { 18 | cout << "Find Process Failed" << endl; 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /Windows/EX_4/Test/WinBaseName.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char const *argv[]) 3 | { 4 | return 0; 5 | } 6 | -------------------------------------------------------------------------------- /Windows/EX_5/README.md: -------------------------------------------------------------------------------- 1 | # 参考文档 2 | 3 | 所有和文件有关的函数: 4 | 5 | 代码示例和讲解: 6 | 7 | 8 | ## 函数 9 | 10 | `CreateFile`函数可以创建或**打开一个现有的文件**。*磁盘文件->文件对象* *似乎文件夹不能这么打开* 11 | 12 | `GetFileAttributes`可以通过返回值判断文件的类型 13 | 14 | `GetFileInformationByHandl`通过这个来获得一个文件的时间戳,这个函数用于时间戳的更改 15 | 16 | `GetFileInformationByHandlEX`获得的文件名是特殊的windows专有格式,这个不要用 17 | 18 | 文件夹也通过这个操作,但是打开后的文件属性不同,操作也不同。 19 | 20 | 文件夹中文件的遍历: 21 | 22 | 使用`FindFirstFile()`获得句柄,再通过`FindNextFile()`遍历,往后依次查找得到文件夹下的文件 23 | 24 | 如果要用MSDN上提供的所有和文件有关的API,最好使用Visual Studio写,MingW-w64有非常多的文件操作接口没实现。 25 | 26 | ## 目前ISSUE 27 | 28 | * ~~文件夹的时间戳(文件夹的CreateFile打开失败了!)~~ 29 | * ~~跨盘符复制~~ 30 | * ~~代码不够优雅~~ 31 | 32 | ## CopyFile的流程 33 | 34 | 1. 首先通过`GetFileAttriputes(文件路径)`来判断对应文件的类型 35 | 1. `if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)`是目录 36 | 37 | 2. 其他则都当作普通文件处理 38 | 39 | 2. 如果是文件 40 | 1. 通过`CreateFile`打开文件句柄。并且将`dwFlagsAndAttributes`设置为`FILE_FLAG_OPEN_REPARSE_POINT`,这样即使打开符号链接,也打开的是对应符号链接的句柄,而不是符号链接所指向路径的文件。 41 | 2. 在新路径下`CreateFile`,并且指定是`CREATE_ALWAYS` 42 | 3. 向新路径写入信息 43 | 1. 使用`ReadFile`和`WriteFile`来为新文件写入信息 44 | 1. `ReadFile`结束标志:函数返回`TRUE`并且`*lpNumberOfBytesRead返回0`。 45 | 2. 后面可以改用区域对象以加快访问速度并减少数据的复制 46 | 4. 使用`GetFileInformationByHandleEx`的`FileBasicInfo`获得老文件的时间信息,在为新文件调用`SetFileInformationByHandle`修改新文件的时间戳。 47 | 3. 如果是目录 48 | 1. 通过`CreateDirectory`在新路径创建文件夹 49 | 2. 使用`FindFirstFile`配合`FindNextFile`来遍历文件夹下的所有文件 50 | 3. 将文件夹下的每个文件都递归调用一次本函数 51 | 4. 使用`CreateFile`同时打开新目录和老目录的文件。并将`dwFlagsAndAttributes`设置为`FILE_FLAG_BACKUP_SEMANTICS`,只有加了这个参数才能打开文件夹的文件句柄。同时注意,`dwDesiredAccess`不能设置为`GENERIC_ALL`,对目录设置这个会打开失败 52 | 5. 使用`GetFileInformationByHandleEx`的`FileBasicInfo`获得老文件的时间信息,在为新文件调用`SetFileInformationByHandle`修改新文件的时间戳。 53 | -------------------------------------------------------------------------------- /Windows/EX_5/Test/CopyDir.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define BUFSIZE 512 9 | 10 | BOOL GetFileNameFromHandle(HANDLE hFile) 11 | { 12 | BOOL bSuccess = FALSE; 13 | TCHAR pszFilename[MAX_PATH + 1]; 14 | HANDLE hFileMap; 15 | 16 | // Get the file size. 17 | DWORD dwFileSizeHi = 0; 18 | DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi); 19 | 20 | if (dwFileSizeLo == 0 && dwFileSizeHi == 0) 21 | { 22 | _tprintf(TEXT("Cannot map a file with a length of zero.\n")); 23 | return FALSE; 24 | } 25 | 26 | // Create a file mapping object. 27 | hFileMap = CreateFileMapping(hFile, 28 | NULL, 29 | PAGE_READONLY, 30 | 0, 31 | 1, 32 | NULL); 33 | 34 | if (hFileMap) 35 | { 36 | // Create a file mapping to get the file name. 37 | void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1); 38 | 39 | if (pMem) 40 | { 41 | if (GetMappedFileName(GetCurrentProcess(), 42 | pMem, 43 | pszFilename, 44 | MAX_PATH)) 45 | { 46 | 47 | // Translate path with device name to drive letters. 48 | TCHAR szTemp[BUFSIZE]; 49 | szTemp[0] = '\0'; 50 | 51 | if (GetLogicalDriveStrings(BUFSIZE - 1, szTemp)) 52 | { 53 | TCHAR szName[MAX_PATH]; 54 | TCHAR szDrive[3] = TEXT(" :"); 55 | BOOL bFound = FALSE; 56 | TCHAR* p = szTemp; 57 | 58 | do 59 | { 60 | // Copy the drive letter to the template string 61 | *szDrive = *p; 62 | 63 | // Look up each device name 64 | if (QueryDosDevice(szDrive, szName, MAX_PATH)) 65 | { 66 | size_t uNameLen = _tcslen(szName); 67 | 68 | if (uNameLen < MAX_PATH) 69 | { 70 | bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0 71 | && *(pszFilename + uNameLen) == _T('\\'); 72 | 73 | if (bFound) 74 | { 75 | // Reconstruct pszFilename using szTempFile 76 | // Replace device path with DOS path 77 | TCHAR szTempFile[MAX_PATH]; 78 | StringCchPrintf(szTempFile, 79 | MAX_PATH, 80 | TEXT("%s%s"), 81 | szDrive, 82 | pszFilename + uNameLen); 83 | StringCchCopyN(pszFilename, MAX_PATH + 1, szTempFile, _tcslen(szTempFile)); 84 | } 85 | } 86 | } 87 | 88 | // Go to the next NULL character. 89 | while (*p++); 90 | } while (!bFound && *p); // end of string 91 | } 92 | } 93 | bSuccess = TRUE; 94 | UnmapViewOfFile(pMem); 95 | } 96 | 97 | CloseHandle(hFileMap); 98 | } 99 | _tprintf(TEXT("File name is %s\n"), pszFilename); 100 | return(bSuccess); 101 | } 102 | 103 | int _tmain(int argc, TCHAR* argv[]) 104 | { 105 | HANDLE hFile; 106 | 107 | if (argc != 2) 108 | { 109 | _tprintf(TEXT("This sample takes a file name as a parameter.\n")); 110 | return 0; 111 | } 112 | hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, 113 | OPEN_EXISTING, 0, NULL); 114 | 115 | if (hFile == INVALID_HANDLE_VALUE) 116 | { 117 | _tprintf(TEXT("CreateFile failed with %d\n"), GetLastError()); 118 | return 0; 119 | } 120 | GetFileNameFromHandle(hFile); 121 | } -------------------------------------------------------------------------------- /Windows/EX_5/Test/CopyFile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | //Win32已经实现了一个CopyFile 4 | int CopyFile(const char *source, const char *dest) 5 | { 6 | //Last error code怎么使用? 7 | HANDLE source_file_h = CreateFileA(source, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //dwSharemode为0时这个文件的Handle在被关闭前都不能被打开 8 | HANDLE dest_file_h = CreateFileA(dest, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 9 | if (source_file_h == INVALID_HANDLE_VALUE || dest_file_h == INVALID_HANDLE_VALUE) 10 | { 11 | perror("Open File Handle ERROR"); 12 | exit(EXIT_FAILURE); 13 | } 14 | 15 | CloseHandle(source_file_h); 16 | CloseHandle(dest_file_h); 17 | } 18 | 19 | int main(int argc, char const *argv[]) 20 | { 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Windows/EX_5/Test/PrintFileName.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | const char *GetFileName(const char *file_path) 5 | { 6 | int len = strlen(file_path) - 1; 7 | for (int i = len; i >= 0; i--) 8 | { 9 | if (file_path[i] == '\\') 10 | { 11 | return (file_path + i + 1); 12 | } 13 | } 14 | return NULL; 15 | } 16 | int main(int argc, char const *argv[]) 17 | { 18 | cout << GetFileName("U:\\root\\Dev\\BIT-OSD\\Windows\\EX_5\\Test") << endl; 19 | } -------------------------------------------------------------------------------- /Windows/EX_5/Test/PrintFileName.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_5/Test/PrintFileName.exe -------------------------------------------------------------------------------- /Windows/EX_5/Test/functionPointer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | void func1(char c) 3 | { 4 | printf("%c\n", c); 5 | } 6 | void func2(char c) 7 | { 8 | printf("%c\n", c + 1); 9 | } 10 | int main(int argc, char const *argv[]) 11 | { 12 | void (*func[2])(char); 13 | char c; 14 | std::cin >> c; 15 | func[0] = func1; 16 | func[1] = func2; 17 | func[0](c); 18 | func[1](c); 19 | // funcarray[0](c); 20 | // funcarray[1](c); 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /Windows/EX_5/Test/functionPointer.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_5/Test/functionPointer.exe -------------------------------------------------------------------------------- /Windows/EX_5/myCp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include //strsafe? 3 | using namespace std; 4 | //Copy file(sourcepath,目标路径) 5 | //从source path得到文件名,附加目标路径得到新路径 6 | //打开attributes判断 7 | //目录: 8 | // 新创建新文件夹 9 | // 遍历当前文件夹文件递归调用Copy file(new sourcepath+new目标路径) 10 | //其他,直接复制 11 | //setinformation来更改时间戳 12 | //关闭句柄 13 | 14 | //已知ISSUE:Windows的“绝对路径命名空间”还未掌握(跨盘符复制未实现); 文件夹时间戳未能成功更改 15 | 16 | //todo: 17 | //+ Windows文件夹对象的打开方法 18 | //+ GetBase重新实现 19 | 20 | const char* GetBaseName(const char* file_path) 21 | { 22 | const char* rt_val = strrchr(file_path, '\\'); 23 | if (rt_val == NULL) 24 | { 25 | return strrchr(file_path, '/'); 26 | } 27 | return rt_val; 28 | } 29 | 30 | int CopyFile(const char* source_file, const char* dest_path) 31 | { 32 | DWORD file_type = GetFileAttributes(source_file); 33 | char* dest_file = (char*)calloc(MAX_PATH, sizeof(char)); 34 | if (dest_file != NULL) 35 | { 36 | sprintf_s(dest_file, MAX_PATH, "%s\\%s", dest_path, GetBaseName(source_file)); 37 | if (file_type == FILE_ATTRIBUTE_DIRECTORY) 38 | { 39 | CreateDirectory(dest_file, NULL); 40 | WIN32_FIND_DATA find_data; 41 | char source_file_dir[MAX_PATH] = { 0 }; 42 | 43 | strncpy_s(source_file_dir, source_file, MAX_PATH - 2); 44 | strcat_s(source_file_dir, MAX_PATH, "\\*"); //打开文件夹还需要后面加* 45 | HANDLE hfind = FindFirstFile(source_file_dir, &find_data); 46 | 47 | if (INVALID_HANDLE_VALUE == hfind) 48 | { 49 | cout << "Open Dir" << source_file << "Error" << endl; 50 | return -1; 51 | } 52 | 53 | int len = strnlen(source_file_dir, MAX_PATH) - 1; 54 | do 55 | { 56 | if (strncmp("..", find_data.cFileName, 3) == 0 || strncmp(".", find_data.cFileName, 2) == 0) 57 | { 58 | continue; 59 | } 60 | 61 | memset(source_file_dir + len, 0, (int)MAX_PATH - len); 62 | strncat(source_file_dir, find_data.cFileName, strlen(find_data.cFileName)); //改造后source_file_dir就变成了需要复制文件的路径 63 | 64 | if (CopyFile(source_file_dir, dest_file) != 0) 65 | { 66 | cout << "Copy " << source_file_dir << " error" << endl; 67 | } 68 | } while (FindNextFile(hfind, &find_data) != 0); 69 | 70 | FindClose(hfind); 71 | } 72 | else 73 | { 74 | //一般文件直接复制 75 | if (!CopyFileEx(source_file, dest_file, NULL, NULL, NULL, 0x800)) //0x800是COPY_FILE_COPY_SYMLINK,但是Mingw不支持 76 | { 77 | return -1; 78 | } 79 | } 80 | 81 | //改时间戳 82 | HANDLE source_file_h = CreateFile(source_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 83 | HANDLE dest_file_h = CreateFile(dest_file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 84 | if (source_file_h == INVALID_HANDLE_VALUE || dest_file_h == INVALID_HANDLE_VALUE) 85 | { 86 | cout << "Open file Handle failed" << endl; 87 | return -1; 88 | } 89 | BY_HANDLE_FILE_INFORMATION file_info; 90 | GetFileInformationByHandle(source_file_h, &file_info); 91 | SetFileTime(dest_file_h, &file_info.ftCreationTime, &file_info.ftLastAccessTime, &file_info.ftLastWriteTime); 92 | CloseHandle(source_file_h); 93 | CloseHandle(dest_file_h); 94 | } 95 | return 0; 96 | } 97 | int main(int argc, char const* argv[]) 98 | { 99 | if (argc >= 3) 100 | { 101 | CopyFile(argv[1], argv[2]); 102 | } 103 | else 104 | { 105 | cout << "Too Little Arguments!" << endl; 106 | } 107 | 108 | return 0; 109 | } -------------------------------------------------------------------------------- /Windows/EX_5/myCp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/EX_5/myCp.exe -------------------------------------------------------------------------------- /Windows/EX_5/mycp_enhanced.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define WIN10_MAX_PATH 32767 4 | using namespace std; 5 | 6 | //Get the base name of the file from a path 7 | LPCSTR GetBaseName(LPCSTR file_path) 8 | { 9 | LPCSTR file_name = strrchr(file_path, '\\'); 10 | if (file_name == NULL) 11 | { 12 | return strrchr(file_path, '/'); 13 | } 14 | return file_name; 15 | } 16 | 17 | int MyCopy(LPCTSTR source_path, LPCTSTR target_path) 18 | { 19 | LPSTR new_file_path = (LPSTR)calloc(WIN10_MAX_PATH, sizeof(CHAR)); 20 | if (new_file_path == NULL) 21 | { 22 | cout << "Path Name Memory Alloc Failed" << endl; 23 | return -1; 24 | } 25 | sprintf_s(new_file_path, WIN10_MAX_PATH, "%s\\%s", target_path, GetBaseName(source_path)); 26 | 27 | 28 | 29 | //judge the file type 30 | DWORD FileAttributes = GetFileAttributes(source_path); 31 | if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY) 32 | { 33 | //directory 34 | CreateDirectoryA(new_file_path, NULL); 35 | 36 | 37 | LPSTR old_dir_path = (LPSTR)calloc(WIN10_MAX_PATH, sizeof(CHAR)); 38 | if (old_dir_path == NULL) 39 | { 40 | cout << "Path Name (new dir) Memory Alloc Failed" << endl; 41 | return -1; 42 | } 43 | strncpy(old_dir_path, source_path, WIN10_MAX_PATH); 44 | int old_dir_path_len = strnlen(old_dir_path, WIN10_MAX_PATH) + 1; 45 | strncat(old_dir_path, "\\*", WIN10_MAX_PATH); 46 | 47 | WIN32_FIND_DATAA find_data; 48 | HANDLE hFind = FindFirstFile(old_dir_path, &find_data); 49 | 50 | do 51 | { 52 | if (strncmp("..", find_data.cFileName, 3) == 0 || strncmp(".", find_data.cFileName, 2) == 0) 53 | { 54 | continue; 55 | } 56 | 57 | //now you have the name of the file in the old path 58 | strcpy(old_dir_path + old_dir_path_len, find_data.cFileName); 59 | //copy to the new directory 60 | if (MyCopy(old_dir_path, new_file_path) != 0) 61 | { 62 | cout << "Copy " << old_dir_path << " error" << endl; 63 | } 64 | 65 | 66 | } while (FindNextFileA(hFind, &find_data) != 0); 67 | 68 | FindClose(hFind); 69 | 70 | //open new directory to modify time stamp 71 | //warning! In windows, it will fail to call this function if you set dwDesiredAccess to GENERIC_ALL instead of GENERIC_READ | GENERIC_WRITE 72 | HANDLE old_dir = CreateFile(source_path, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 73 | HANDLE new_dir = CreateFile(new_file_path, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 74 | 75 | if (old_dir == INVALID_HANDLE_VALUE || new_dir == INVALID_HANDLE_VALUE) 76 | { 77 | cout << "Modify time stamp error" << endl; 78 | } 79 | FILE_BASIC_INFO basic_info; 80 | 81 | GetFileInformationByHandleEx(old_dir, FileBasicInfo, &basic_info, sizeof(basic_info)); 82 | SetFileInformationByHandle(new_dir, FileBasicInfo, &basic_info, sizeof(basic_info)); 83 | CloseHandle(new_dir); 84 | CloseHandle(old_dir); 85 | free(old_dir_path); 86 | } 87 | else 88 | { 89 | //file 90 | HANDLE old_file = CreateFile(source_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL); 91 | HANDLE new_file = CreateFile(new_file_path, GENERIC_ALL, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_OPEN_REPARSE_POINT, NULL); 92 | if (old_file == INVALID_HANDLE_VALUE || new_file == INVALID_HANDLE_VALUE) 93 | { 94 | cout << "Open " << old_file << " error" << endl; 95 | return -1; 96 | } 97 | CHAR BUFFER[4096]; 98 | while (true) 99 | { 100 | DWORD number_readed = 0; 101 | if (ReadFile(old_file, &BUFFER[0], 4096, &number_readed, NULL)) 102 | { 103 | if (number_readed == 0) 104 | { 105 | break; 106 | } 107 | DWORD number_writed = 0; 108 | WriteFile(new_file, BUFFER, number_readed, &number_writed, 0); 109 | if (number_writed == 0) 110 | { 111 | break; 112 | } 113 | } 114 | else 115 | { 116 | break; 117 | } 118 | } 119 | _FILE_BASIC_INFO basic_info; 120 | GetFileInformationByHandleEx(old_file, FileBasicInfo, &basic_info, sizeof(basic_info)); 121 | SetFileInformationByHandle(new_file, FileBasicInfo, &basic_info, sizeof(basic_info)); 122 | CloseHandle(new_file); 123 | CloseHandle(old_file); 124 | } 125 | 126 | free(new_file_path); 127 | return 0; 128 | } 129 | 130 | int main(int argc, char const* argv[]) 131 | { 132 | if (argc >= 3) 133 | { 134 | MyCopy(argv[1], argv[2]); 135 | } 136 | else 137 | { 138 | 139 | cout << "Too Little Arguments!" << endl; 140 | } 141 | 142 | return 0; 143 | } -------------------------------------------------------------------------------- /Windows/OSD-Windows.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30717.126 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OSD-Windows", "OSD-Windows.vcxproj", "{32D75545-17AE-46A8-ACAF-1E251D73DE15}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM64 = Debug|ARM64 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|ARM64 = Release|ARM64 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Debug|ARM64.ActiveCfg = Debug|ARM64 19 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Debug|ARM64.Build.0 = Debug|ARM64 20 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Debug|x64.ActiveCfg = Debug|x64 21 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Debug|x64.Build.0 = Debug|x64 22 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Debug|x86.ActiveCfg = Debug|Win32 23 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Debug|x86.Build.0 = Debug|Win32 24 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Release|ARM64.ActiveCfg = Release|ARM64 25 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Release|ARM64.Build.0 = Release|ARM64 26 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Release|x64.ActiveCfg = Release|x64 27 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Release|x64.Build.0 = Release|x64 28 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Release|x86.ActiveCfg = Release|Win32 29 | {32D75545-17AE-46A8-ACAF-1E251D73DE15}.Release|x86.Build.0 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {5759D68C-1DE7-42B7-8E4B-64C9D672903C} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /Windows/OSD-Windows.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | ARM64 7 | 8 | 9 | Debug 10 | Win32 11 | 12 | 13 | Release 14 | ARM64 15 | 16 | 17 | Release 18 | Win32 19 | 20 | 21 | Debug 22 | x64 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | 31 | 32 | 33 | 16.0 34 | {32D75545-17AE-46A8-ACAF-1E251D73DE15} 35 | Win32Proj 36 | 37 | 38 | 39 | Application 40 | true 41 | v142 42 | 43 | 44 | Application 45 | false 46 | v142 47 | 48 | 49 | Application 50 | true 51 | v142 52 | 53 | 54 | Application 55 | true 56 | v142 57 | 58 | 59 | Application 60 | false 61 | v142 62 | NotSet 63 | true 64 | 65 | 66 | Application 67 | false 68 | v142 69 | NotSet 70 | true 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 | true 98 | 99 | 100 | true 101 | 102 | 103 | true 104 | 105 | 106 | true 107 | 108 | 109 | 110 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 111 | MultiThreadedDebugDLL 112 | Level3 113 | ProgramDatabase 114 | Disabled 115 | 116 | 117 | MachineX86 118 | true 119 | Console 120 | 121 | 122 | 123 | 124 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 125 | MultiThreadedDLL 126 | Level3 127 | ProgramDatabase 128 | 129 | 130 | MachineX86 131 | true 132 | Windows 133 | true 134 | true 135 | 136 | 137 | 138 | 139 | Level3 140 | 141 | 142 | 143 | 144 | Level3 145 | 146 | 147 | 148 | 149 | true 150 | MinSpace 151 | 152 | 153 | Console 154 | true 155 | true 156 | UseFastLinkTimeCodeGeneration 157 | 158 | 159 | 160 | 161 | true 162 | MinSpace 163 | 164 | 165 | Console 166 | true 167 | true 168 | UseFastLinkTimeCodeGeneration 169 | 170 | 171 | 172 | 173 | Console 174 | 175 | 176 | 177 | 178 | Console 179 | 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /Windows/OSD-Windows.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Windows/README.md: -------------------------------------------------------------------------------- 1 | * 实验一: 编译内核 2 | * 实验二(EX_2):启动进程`start process` 3 | * 实验三(EX_3):生产者消费者 4 | * 实验四(EX_4):实现进程资源查看器 5 | * 实验五(EX_5):实现递归移动整个文件夹的`myCp` 6 | -------------------------------------------------------------------------------- /Windows/Test/wmain.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I-Rinka/BIT-OSD/2542be64654c5068e42f9adb32741dc3cd5479da/Windows/Test/wmain.cpp --------------------------------------------------------------------------------