-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
1776 lines (1763 loc) · 404 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>http://yuanmxc.site</id>
<title>陌上尘归处</title>
<subtitle>人生无根蒂,飘如陌上尘</subtitle>
<icon>http://yuanmxc.site/images/favicon.ico</icon>
<link href="http://yuanmxc.site" />
<author>
<name>陌上尘</name>
</author>
<updated>2024-07-20T05:11:46.531Z</updated>
<entry>
<id>http://yuanmxc.site/%E7%AC%94%E8%AE%B0/ArchLinux%20%E5%AE%89%E8%A3%85%20CUDA%20%E3%80%81TensorRT%20%20%E5%92%8CTensorRT-YOLO%20%E8%AE%B0%E5%BD%95/</id>
<title></title>
<link rel="alternate" href="http://yuanmxc.site/%E7%AC%94%E8%AE%B0/ArchLinux%20%E5%AE%89%E8%A3%85%20CUDA%20%E3%80%81TensorRT%20%20%E5%92%8CTensorRT-YOLO%20%E8%AE%B0%E5%BD%95/"/>
<content type="html"><h1 id="archlinux-安装-cuda-tensorrt-和tensorrt-yolo-记录"><a class="anchor" href="#archlinux-安装-cuda-tensorrt-和tensorrt-yolo-记录">#</a> ArchLinux 安装 CUDA 、TensorRT 和 TensorRT-YOLO 记录</h1>
<h2 id="安装tensorrt-和-cuda"><a class="anchor" href="#安装tensorrt-和-cuda">#</a> 安装 TensorRT 和 CUDA</h2>
<ol>
<li>
<p>根据 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2xhdWdoMTIzMjEvVGVuc29yUlQtWU9MTw==">TensorRT-YOLO</span> Github 页面使用教程中的 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2xhdWdoMTIzMjEvVGVuc29yUlQtWU9MTy9ibG9iL21haW4vZG9jcy9jbi9idWlsZF9hbmRfaW5zdGFsbC5tZA==">快速编译安装 </span> 进行,编译前首先要安装 xmake CUDA 和 TensorRT。</p>
<p>xmake 简单,只需要:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>yay <span class="token parameter variable">-S</span> xmake</pre></td></tr></table></figure></li>
<li>
<p>安装 CUDA 和 TensorRT</p>
<ul>
<li>
<p>安装 CUDA :</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>yay <span class="token parameter variable">-S</span> cuda</pre></td></tr></table></figure><p>版本为最新版 cuda-12.5.1-1</p>
</li>
<li>
<p>在安装 TensorRT :</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>yay <span class="token parameter variable">-S</span> tensorrt</pre></td></tr></table></figure><p>遇到错误,AUR 提供的 TensorRT 目前仍是 10.1.0.27-1 版本,而 CUDA 和 TensorRT 的版本必须是一一对应的,TensorRT 使用 CUDA 。</p>
<p>吐槽一下,“适配” 这件事做的不是很好,摘自 Archlinux AUR 的 <span class="exturl" data-url="aHR0cHM6Ly9hdXIuYXJjaGxpbnV4Lm9yZy9wYWNrYWdlcy90ZW5zb3JydA==">tensorrt</span> 软件包下一个老哥的评论(已置顶):</p>
<blockquote>
<p>它(指 AUR 提供的 tensorrt 10.1.0.27-1)无法针对 cuda 12.5 构建,将 cuda 降级到 12.4.1,它将起作用。长话短说:关于这一点有两个问题。首先,tensorrt 10.0.1 显然不支持 cuda 12.5,正如您在<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL05WSURJQS9UZW5zb3JSVC90cmVlL3YxMC4wLjE/dGFiPXJlYWRtZS1vdi1maWxlI29wdGlvbmFsLS0taWYtbm90LXVzaW5nLXRlbnNvcnJ0LWNvbnRhaW5lci1zcGVjaWZ5LXRoZS10ZW5zb3JydC1nYS1yZWxlYXNlLWJ1aWxkLXBhdGg=">上游文档</span>中看到的那样。其次,官方仓库中提供的当前版本的 nvidia 驱动程序不支持 cuda 12.5(cuda 12.5 是在没有支持它的驱动程序的情况下推送的),您可以在<span class="exturl" data-url="aHR0cHM6Ly9naXRsYWIuYXJjaGxpbnV4Lm9yZy9hcmNobGludXgvcGFja2FnaW5nL3BhY2thZ2VzL2N1ZGEvLS9pc3N1ZXMvNw==">此链接</span>的 Arch Linux cuda 软件包问题页面中阅读更多详细信息。</p>
</blockquote>
<p>两个解决办法:</p>
<ol>
<li>
<p>使用 downgrade 降级 CUDA 到 12.4.1 :</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> downgrade cuda</pre></td></tr></table></figure><p>但是下载速度异常缓慢,几十 kb 每秒(刚开始还比较快),故放弃。</p>
<p>我也尝试过在英伟达官网进行下载 CUDA ,首先你必须注册一个账号,其次,官网上 CUDA 只支持特定的几个 Linux 发行版,其中刚好没有 ArchLinux(那 AUR 的软件包是从何而来的?)</p>
</li>
<li>
<p>手动安装 TensorRT 的 10.2.0 版本:</p>
<p>在 NVIDIA 的 GitHub <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL05WSURJQS9UZW5zb3JSVA==">TensorRT</span> 下克隆存储库并进行安装。</p>
<p>原本打算在本机上进行安装,最后 cmake 时遇到报错,问 GPT 说是 gcc 版本和 CUDA 的编译器 nvcc 版本的问题,继续查。</p>
<p>最后发现 CUDA 12.4, 12.5 版本最大支持的 GCC 版本竟然是 13.2。查看本机的 gcc 版本为:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>gcc <span class="token parameter variable">-v</span></pre></td></tr><tr><td data-num="2"></td><td><pre>gcc 版本 <span class="token number">14.1</span>.1 <span class="token number">20240522</span> <span class="token punctuation">(</span>GCC<span class="token punctuation">)</span></pre></td></tr></table></figure><p>而其我并不是在英伟达官网找到的(没找到,理论上应该有),是 Google 之后在 <span class="exturl" data-url="aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNjYyMjQ1NC9jdWRhLWluY29tcGF0aWJsZS13aXRoLW15LWdjYy12ZXJzaW9u">一篇帖子</span> 下的评论找到的,这篇帖子发布于 2011 年,但我甚至能看到今年的评论。</p>
<p>评论的老哥给了一个 CUDA 版本和其支持的最高 GCC 版本的对应表格以及更多信息,首次评论在 Sep 23, 2017 at 14:23 ,最新编辑在 <span class="exturl" data-url="aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9wb3N0cy80NjM4MDYwMS9yZXZpc2lvbnM=">Jun 18 at 19:16</span> ,应该是相关开发人员?</p>
<p>因为降级 gcc 会破坏其他依赖,无法降级,本来打算按教程使用 docker 来用的,但是这位老哥下面给出了方法,简单来说就是安装旧版本的 gcc ,之后让 CUDA 的编译器 nvcc 使用旧版本的 gcc。</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token comment"># 安装适配的旧版本 gcc</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">sudo</span> pacmane <span class="token parameter variable">-S</span> gcc13</pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token comment"># 在 CUDA 文件夹中添加符号链接:</span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token builtin class-name">cd</span> /opt/cuda</pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token function">sudo</span> <span class="token function">ln</span> <span class="token parameter variable">-s</span> /usr/bin/gcc-13 /usr/local/cuda/bin/gcc </pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token function">sudo</span> <span class="token function">ln</span> <span class="token parameter variable">-s</span> /usr/bin/g++-13 /usr/local/cuda/bin/g++</pre></td></tr></table></figure><p>这位老哥的评论下最新的评论在 <span class="exturl" data-url="aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNjYyMjQ1NC9jdWRhLWluY29tcGF0aWJsZS13aXRoLW15LWdjYy12ZXJzaW9uI2NvbW1lbnQxMzcyNjE2ODVfNDYzODA2MDE=">CommentedJan 22 at 12:27</span> ,方法有用。</p>
</li>
</ol>
</li>
</ul>
</li>
<li>
<p>在解决了各种版本问题后,我目前安装的环境如下:</p>
<ul>
<li>
<p>ArchLinux AUR 安装的 cuda-12.5.1-1。</p>
</li>
<li>
<p>在 NVIDIA 的 GitHub <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL05WSURJQS9UZW5zb3JSVC9yZWxlYXNlcw==">TensorRT Releases </span> 安装的 TensorRT OSS v10.2.0 存储库。</p>
</li>
<li>
<p>yay 安装 cuda-12.5.1-1 时安装 cuda-cudnn-9.2.0.82-1。</p>
</li>
<li>
<p>指定上面安装的 gcc13 ,让 CUDA 的编译器 nvcc 使用。</p>
</li>
</ul>
<p>然后按照在 NVIDIA 的 GitHub <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL05WSURJQS9UZW5zb3JSVCNidWlsZA==">TensorRT Build</span> 的教程进行安装。</p>
<p>根据上面写的推荐版本 cuda-12.5.0 + cuDNN-8.9 ,使用 downgrade 降级安装 cuDNN-8.9 版本。</p>
<p>最后至此开始正式 build。</p>
</li>
<li>
<p>按教程安装 <span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9kb3dubG9hZHMvY29tcHV0ZS9tYWNoaW5lLWxlYXJuaW5nL3RlbnNvcnJ0LzEwLjIuMC90YXJzL1RlbnNvclJULTEwLjIuMC4xOS5MaW51eC54ODZfNjQtZ251LmN1ZGEtMTIuNS50YXIuZ3o=">TensorRT 10.2.0.19 for CUDA 12.5, Linux x86_64</span> ,解压并设置 <code>TRT_LIBPATH</code> 到~/.zshrc ,然后在 TensorRT 目录下执行下面操作:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token builtin class-name">cd</span> <span class="token variable">$TRT_OSSPATH</span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token function">mkdir</span> <span class="token parameter variable">-p</span> build <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">cd</span> build</pre></td></tr><tr><td data-num="3"></td><td><pre> cmake <span class="token punctuation">..</span> <span class="token parameter variable">-DTRT_LIB_DIR</span><span class="token operator">=</span><span class="token variable">$TRT_LIBPATH</span> <span class="token parameter variable">-DTRT_OUT_DIR</span><span class="token operator">=</span><span class="token variable"><span class="token variable">`</span><span class="token builtin class-name">pwd</span><span class="token variable">`</span></span>/out</pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token function">make</span> -j<span class="token variable"><span class="token variable">$(</span>nproc<span class="token variable">)</span></span></pre></td></tr></table></figure><p>cmake 遇到部分警告,make 遇到错误。而且报错似乎是代码方面的错误,多方查阅也没有解决。放弃。</p>
</li>
<li>
<p>第二天,由于 NVIDIA 的 GitHub <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL05WSURJQS9UZW5zb3JSVCNidWlsZA==">TensorRT Build</span> 的教程所给示例都是 Ubuntu 的,并且 英伟达官网的 CUDA 也没有提供 Archlinux 版本。怀疑是不是因为系统的原因。今天尝试降级 cuda 发现下载速度不再缓慢,于是换成上面第二个方案。</p>
</li>
<li>
<p>使用 yay 安装 tensorRT 安装的是 tensorrt-10.1.0.27-1 版本,查看对应的 cuda 版本为 cuda-12.4.0 + cuDNN-8.9,两个都降级到对应版本。yay 安装。</p>
<p>有警告,单线程很慢,但是好得没报错,突然想起一个问题,在 NVIDIA 的 GitHub <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL05WSURJQS9UZW5zb3JSVCNidWlsZA==">TensorRT Build</span> 的教程中让安装了 <span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9kb3dubG9hZHMvY29tcHV0ZS9tYWNoaW5lLWxlYXJuaW5nL3RlbnNvcnJ0LzEwLjIuMC90YXJzL1RlbnNvclJULTEwLjIuMC4xOS5MaW51eC54ODZfNjQtZ251LmN1ZGEtMTIuNS50YXIuZ3o=">TensorRT 10.2.0.19 for CUDA 12.5, Linux x86_64</span> ,这个东西当时我在使用 yay 安装 TrnsorRT 时没有安装,也看到 <span class="exturl" data-url="aHR0cHM6Ly9pdm9uYmxvZy5jb20vcG9zdHMvYXJjaGxpbnV4LWluc3RhbGwtbnZpZGlhLWRyaXZlcnMv">这篇帖子</span> 说到这点:</p>
<blockquote>
<ol>
<li>因為軟體授權限制,無法直接用 yay 裝,需要手動複製 AUR 儲存庫</li>
</ol>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-S</span> base-devel</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">git</span> clone https://aur.archlinux.org/tensorrt.git</pre></td></tr></table></figure><ol>
<li>然後到<span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9udmlkaWEtdGVuc29ycnQtZG93bmxvYWQ="> Nvidia 官網</span>註冊帳號,下載 <code>tar.gz</code> 檔 (注意版本需跟 CUDA 一致),放到 <code>tensorrt</code> 目錄</li>
</ol>
</blockquote>
<p>原文就是繁体,这里说的去官网注册账号下载 <code>tar.gz</code> 檔说的就是 <span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9kb3dubG9hZHMvY29tcHV0ZS9tYWNoaW5lLWxlYXJuaW5nL3RlbnNvcnJ0LzEwLjIuMC90YXJzL1RlbnNvclJULTEwLjIuMC4xOS5MaW51eC54ODZfNjQtZ251LmN1ZGEtMTIuNS50YXIuZ3o=">TensorRT 10.2.0.19 for CUDA 12.5, Linux x86_64</span> 这个东西,叫作 TensorRT GA ,在 TensorRT 安装时需要指定 TensorRT GA 发布构建路径。</p>
<p>所以在我在上面安装了 TensorRT GA 并将其路径添加到~/.zshrc 之后,重新使用 yay 安装就成功了(当时没有发现错误是因为没有找到 TensorRT GA 是因为什么,它没写?还是我没仔细看,绕了一大圈),后来发现 CUDA 版本也是最新版,依然可以使用 yay 安装。(也就是说不用降级也可以,高版本 CUDA 是支持低版本 TensorRT 的)。</p>
<p>所以总结一下 CUDA 通过 yay 直接安装,TensorRT 在通过 yay 安装之前需要先安装 <span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9kb3dubG9hZHMvY29tcHV0ZS9tYWNoaW5lLWxlYXJuaW5nL3RlbnNvcnJ0LzEwLjIuMC90YXJzL1RlbnNvclJULTEwLjIuMC4xOS5MaW51eC54ODZfNjQtZ251LmN1ZGEtMTIuNS50YXIuZ3o=">TensorRT 10.2.0.19 for CUDA 12.5, Linux x86_64</span> 并设置环境变量指定路径。之后也可以通过 yay 安装。</p>
<p>回顾一下 Archlinux AUR 的 <span class="exturl" data-url="aHR0cHM6Ly9hdXIuYXJjaGxpbnV4Lm9yZy9wYWNrYWdlcy90ZW5zb3JydA==">tensorrt</span> 软件包下一个老哥的评论上说明的两个问题,第一个问题:</p>
<p>CUDA 12.4 适用于 TensorRT 10.1.0.27。 CUDA 12.5 适用于 TensorRT 10.2.0.19。1 我这里下载的是后者,后面 <code>tensorrt_yolo</code> 指定的路径也是 TensorRT 10.2.0.19 。</p>
<p>第二个问题是英伟达没有提供驱动,这个问题已经解决了,目前最新的驱动已经支持。</p>
<p>不管如何 CUDA 和 TensorRT 总算是装好了。</p>
</li>
</ol>
<h2 id="tensorrt_yolo"><a class="anchor" href="#tensorrt_yolo">#</a> <code>tensorrt_yolo</code></h2>
<p><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2xhdWdoMTIzMjEvVGVuc29yUlQtWU9MTy9ibG9iL21haW4vZG9jcy9jbi9idWlsZF9hbmRfaW5zdGFsbC5tZA==">TensorRT-YOLO/docs/cn/build_and_install.md </span></p>
<h2 id="deploy-编译"><a class="anchor" href="#deploy-编译">#</a> <code>Deploy</code> 编译</h2>
<p>按照上面给的文档进行编译安装。</p>
<p>本机环境:</p>
<ul>
<li>Linux: gcc/g++ 13.3.0(不知道上面降级和使用旧的 gcc 是否有影作用)</li>
<li>Xmake v2.9.3+20240624</li>
<li>CUDA 12.5.1-1</li>
<li>TensorRT 10.1.0.27-1</li>
</ul>
<p>为了满足部署需求,您可以使用 Xmake 进行 <code>Deploy</code> 编译。此过程支持动态库和静态库的编译:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">git</span> clone https://github.com/laugh12321/TensorRT-YOLO</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token builtin class-name">cd</span> TensorRT-YOLO</pre></td></tr><tr><td data-num="3"></td><td><pre>xmake f <span class="token parameter variable">-k</span> shared <span class="token parameter variable">--tensorrt</span><span class="token operator">=</span><span class="token string">"C:/Program Files/NVIDIA GPU Computing Toolkit/TensorRT/v8.6.1.6"</span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token comment"># xmake f -k static --tensorrt="C:/Program Files/NVIDIA GPU Computing Toolkit/TensorRT/v8.6.1.6"</span></pre></td></tr><tr><td data-num="5"></td><td><pre>xmake <span class="token parameter variable">-P</span> <span class="token builtin class-name">.</span> <span class="token parameter variable">-r</span></pre></td></tr></table></figure><p><code>--tensorrt=&quot;C:/Program Files/NVIDIA GPU Computing Toolkit/TensorRT/v8.6.1.6&quot;</code> 的路径替换为自己的路径,这个路径经过我的探索,最后发现实际在 <span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9kb3dubG9hZHMvY29tcHV0ZS9tYWNoaW5lLWxlYXJuaW5nL3RlbnNvcnJ0LzEwLjIuMC90YXJzL1RlbnNvclJULTEwLjIuMC4xOS5MaW51eC54ODZfNjQtZ251LmN1ZGEtMTIuNS50YXIuZ3o=">TensorRT 10.2.0.19 for CUDA 12.5, Linux x86_64</span> 下,在我这里是: <code>your_path/TensorRT-10.2.0.19/targets/x86_64-linux-gnu/</code></p>
<h2 id="编译安装-tensorrt_yolo"><a class="anchor" href="#编译安装-tensorrt_yolo">#</a> 编译安装 <code>tensorrt_yolo</code></h2>
<p>跳过 PyPI 安装 <code>tensorrt_yolo</code> 模块部分。</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>pip <span class="token function">install</span> <span class="token parameter variable">--upgrade</span> build</pre></td></tr><tr><td data-num="2"></td><td><pre>python <span class="token parameter variable">-m</span> build <span class="token parameter variable">--wheel</span></pre></td></tr><tr><td data-num="3"></td><td><pre>pip <span class="token function">install</span> dist/tensorrt_yolo/tensorrt_yolo-4.*-py3-none-any.whl</pre></td></tr></table></figure><p>上面是文档给的步骤,在 TensorRT-YOLO 下 执行,第三个路径在我这里不争取。我这里对应的文件是是: <code>TensorRT-YOLO/dist/tensorrt_yolo-4.0.0-py3-none-any.whl</code> ,因此路径写 <code> dist/tensorrt_yolo-4.0.0-py3-none-any.whl</code> 。</p>
<h2 id="跑模型推理示例"><a class="anchor" href="#跑模型推理示例">#</a> 跑模型推理示例</h2>
<p>按照 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2xhdWdoMTIzMjEvVGVuc29yUlQtWU9MTy9ibG9iL21haW4vZGVtby9kZXRlY3QvUkVBRE1FLm1k">模型推理示例</span> 进行。</p>
<h3 id="模型导出"><a class="anchor" href="#模型导出">#</a> 模型导出</h3>
<p>首先,从 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3VsdHJhbHl0aWNzL2Fzc2V0cy9yZWxlYXNlcy9kb3dubG9hZC92OC4yLjAveW9sb3Y4cy5wdA==">YOLOv8s</span> 下载 YOLOv8s 模型并保存到 <code>models</code> 文件夹中。</p>
<p>注:上面是原文,这里的 <code>models</code> 文件夹经过我实际测试,实际上是 <code>/TensorRT-YOLO/demo/detect/</code> 下的 models 文件夹。同时工作目录现在默认也是 <code>/TensorRT-YOLO/demo/detect/</code> 。</p>
<p>然后,使用以下指令将模型导出为带有 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL05WSURJQS9UZW5zb3JSVC90cmVlL21haW4vcGx1Z2luL2VmZmljaWVudE5NU1BsdWdpbg==">EfficientNMS</span> 插件的 ONNX 格式:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>trtyolo <span class="token builtin class-name">export</span> <span class="token parameter variable">-w</span> yolov8s.pt <span class="token parameter variable">-v</span> yolov8 <span class="token parameter variable">-o</span> models</pre></td></tr></table></figure><p>执行以上命令后,将在 <code>models</code> 文件夹下生成名为 <code>yolov8s.onnx</code> 的文件。然后,使用 <code>trtexec</code> 工具将 ONNX 文件转换为 TensorRT engine:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>trtexec <span class="token parameter variable">--onnx</span><span class="token operator">=</span>models/yolov8s.onnx <span class="token parameter variable">--saveEngine</span><span class="token operator">=</span>models/yolov8s.engine <span class="token parameter variable">--fp16</span></pre></td></tr></table></figure><p>到这里都没哟遇到什么错误,第二个命令运行时我这里看起来像卡住了一样,不过最终是跑通了的。</p>
<h3 id="模型推理"><a class="anchor" href="#模型推理">#</a> 模型推理</h3>
<p>这里只讲 C++ 部分。</p>
<p>使用 C++ 进行推理前,请确保您已按照 <span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2xhdWdoMTIzMjEvVGVuc29yUlQtWU9MTy9ibG9iL21haW4vZG9jcy9jbi9idWlsZF9hbmRfaW5zdGFsbC5tZCNkZXBsb3ktJUU3JUJDJTk2JUU4JUFGJTkx">Deploy 编译指南</span> 对 Deploy 进行了编译。</p>
<p>接着,使用 xmake 将 <code>detect.cpp</code> 编译为可执行文件:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>xmake f <span class="token parameter variable">-P</span> <span class="token builtin class-name">.</span> <span class="token parameter variable">--tensorrt</span><span class="token operator">=</span><span class="token string">"/path/to/your/TensorRT"</span> <span class="token parameter variable">--deploy</span><span class="token operator">=</span>/path/to/your/TensorRT-YOLO</pre></td></tr><tr><td data-num="2"></td><td><pre></pre></td></tr><tr><td data-num="3"></td><td><pre>xmake <span class="token parameter variable">-P</span> <span class="token builtin class-name">.</span> <span class="token parameter variable">-r</span></pre></td></tr></table></figure><p>注:上面是原文,这里的 <code>&quot;/path/to/your/TensorRT&quot;</code> 就是前面安装的 <span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9kb3dubG9hZHMvY29tcHV0ZS9tYWNoaW5lLWxlYXJuaW5nL3RlbnNvcnJ0LzEwLjIuMC90YXJzL1RlbnNvclJULTEwLjIuMC4xOS5MaW51eC54ODZfNjQtZ251LmN1ZGEtMTIuNS50YXIuZ3o=">TensorRT 10.2.0.19 for CUDA 12.5, Linux x86_64</span> 下的一个路径, <code>your_path/TensorRT-10.2.0.19/targets/x86_64-linux-gnu/</code> 。后面的 deploy 路径就是你的 TensorRT-YOLO 路径。</p>
<p>在执行上述命令后,将在根目录的 <code>build</code> 目录下生成名为 <code>detect</code> 的可执行文件。最后,您可以直接运行可执行文件或使用 <code>xmake run</code> 命令进行推理。使用 <code>--help</code> 查看详细指令选项:</p>
<p>注;上面是原文,我这里生成的 <code>detect</code> 的可执行文件位于 <code>/TensorRT-YOLO/demo/detect/build/linux/x86_64/release/</code> 下,同时还有一个 <code>libdeploy.so</code> 文件也在这个目录下。</p>
<blockquote>
<p>要加速推理过程,请使用 <code>--cudaGraph</code> 指令,但此功能仅支持静态模型,不支持动态模型。</p>
</blockquote>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>xmake run <span class="token parameter variable">-P</span> <span class="token builtin class-name">.</span> detect <span class="token parameter variable">-e</span> models/yolov8s.engine <span class="token parameter variable">-i</span> images <span class="token parameter variable">-o</span> output <span class="token parameter variable">-l</span> labels.txt <span class="token parameter variable">--cudaGraph</span></pre></td></tr></table></figure><p>注:这里命令中的路径一定要正确,工作目录在 <code>/TensorRT-YOLO/demo/detect/</code> 下时,为:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>./build/linux/x86_64/release/detect <span class="token parameter variable">-e</span> models/yolov8s.engine <span class="token parameter variable">-i</span> images <span class="token parameter variable">-o</span> output <span class="token parameter variable">-l</span> labels.txt <span class="token parameter variable">--cudaGraph</span></pre></td></tr></table></figure><p>使用 xmake run 的命令没去试,直接运行 detect 就行了。输出图像在 output 文件夹下,生成文本描述 <code>labels.txt</code> 。</p>
</content>
<updated>2024-07-20T05:11:46.531Z</updated>
</entry>
<entry>
<id>http://yuanmxc.site/C++/C++%E5%87%BD%E6%95%B0/</id>
<title>C++ 函数</title>
<link rel="alternate" href="http://yuanmxc.site/C++/C++%E5%87%BD%E6%95%B0/"/>
<content type="html"><ol>
<li>
<p>根据高分辨率的时钟为种子,生成指定长度的随机 ID 的函数</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token comment">// 生成指定长度的随机 ID</span></pre></td></tr><tr><td data-num="2"></td><td><pre>std<span class="token double-colon punctuation">::</span>string <span class="token function">randomId</span><span class="token punctuation">(</span>size_t length<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="3"></td><td><pre> <span class="token keyword">using</span> std<span class="token double-colon punctuation">::</span>chrono<span class="token double-colon punctuation">::</span>high_resolution_clock<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token keyword">static</span> <span class="token keyword">thread_local</span> std<span class="token double-colon punctuation">::</span>mt19937 <span class="token function">rng</span><span class="token punctuation">(</span></pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>high_resolution_clock<span class="token double-colon punctuation">::</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">time_since_epoch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">count</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token keyword">static</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token function">characters</span><span class="token punctuation">(</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token string">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> std<span class="token double-colon punctuation">::</span>string <span class="token function">id</span><span class="token punctuation">(</span>length<span class="token punctuation">,</span> <span class="token char">'0'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="9"></td><td><pre> std<span class="token double-colon punctuation">::</span>uniform_int_distribution<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">></span> <span class="token function">uniform</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">(</span>characters<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="10"></td><td><pre> std<span class="token double-colon punctuation">::</span><span class="token function">generate</span><span class="token punctuation">(</span>id<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> id<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">&amp;</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token keyword">return</span> characters<span class="token punctuation">.</span><span class="token function">at</span><span class="token punctuation">(</span><span class="token function">uniform</span><span class="token punctuation">(</span>rng<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token keyword">return</span> id<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">using</span> std<span class="token double-colon punctuation">::</span>chrono<span class="token double-colon punctuation">::</span>high_resolution_clock<span class="token punctuation">;</span> <span class="token comment">// 这行代码引入了 `std::chrono::high_resolution_clock`,这是一个用于测量时间的标准库类。</span></pre></td></tr></table></figure><figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">static</span> <span class="token keyword">thread_local</span> std<span class="token double-colon punctuation">::</span>mt19937 <span class="token function">rng</span><span class="token punctuation">(</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token generic-function"><span class="token function">static_cast</span><span class="token generic class-name"><span class="token operator">&lt;</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span><span class="token operator">></span></span></span><span class="token punctuation">(</span>high_resolution_clock<span class="token double-colon punctuation">::</span><span class="token function">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">time_since_epoch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">count</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>这行代码定义了一个静态局部变量 <code>rng</code> ,它是一个 <code>std::mt19937</code> 类型的伪随机数生成器。通过使用当前时间的高分辨率时钟的计数作为种子,我们创建了一个每次函数调用时都会生成不同随机数序列的生成器。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">static</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token function">characters</span><span class="token punctuation">(</span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token string">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>这行代码定义了一个静态常量字符串 <code>characters</code> ,它包含了用于生成随机 ID 的字符集。它包括数字、大写字母和小写字母。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre>std<span class="token double-colon punctuation">::</span>string <span class="token function">id</span><span class="token punctuation">(</span>length<span class="token punctuation">,</span> <span class="token char">'0'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>这行代码创建了一个名为 <code>id</code> 的 <code>std::string</code> 对象,长度为 <code>length</code> ,并将其初始化为由字符 <code>'0'</code> 组成的字符串。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre>std<span class="token double-colon punctuation">::</span>uniform_int_distribution<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">></span> <span class="token function">uniform</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">(</span>characters<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>这行代码定义了一个均匀分布的整数生成器 <code>uniform</code> ,它生成范围在 <code>0</code> 到 <code>characters.size() - 1</code> 之间的整数。</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre>std<span class="token double-colon punctuation">::</span><span class="token function">generate</span><span class="token punctuation">(</span>id<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> id<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">&amp;</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span> <span class="token keyword">return</span> characters<span class="token punctuation">.</span><span class="token function">at</span><span class="token punctuation">(</span><span class="token function">uniform</span><span class="token punctuation">(</span>rng<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">&#125;</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr></table></figure><p>这行代码使用 <code>std::generate</code> 算法,将随机选择的字符填充到 <code>id</code> 字符串中。 <code>generate</code> 函数接受一个范围(由 <code>id.begin()</code> 和 <code>id.end()</code> 表示),并使用 lambda 表达式作为生成器函数。lambda 表达式使用 <code>characters</code> 字符串和 <code>uniform(rng)</code> 生成的随机索引来填充字符。</p>
</li>
</ol>
</content>
<category term="C++" scheme="http://yuanmxc.site/categories/C/" />
<updated>2024-06-02T03:17:03.979Z</updated>
</entry>
<entry>
<id>http://yuanmxc.site/C++/C++%E5%B0%8F%E8%AE%B0/</id>
<title>C++ 小记</title>
<link rel="alternate" href="http://yuanmxc.site/C++/C++%E5%B0%8F%E8%AE%B0/"/>
<content type="html"><ol>
<li>
<p><code>std::holds_alternative&lt;std::string&gt;(data)</code> 是一个类型检查的表达式,用于检查给定的变量 <code>data</code> 是否包含 <code>std::string</code> 类型的值。</p>
<p><code>std::holds_alternative</code> 是 C++ 标准库中的一个函数模板,它的作用是判断给定的变量是否包含指定的类型。</p>
</li>
<li>
<p><code>std::promise&lt;void&gt;</code> 是 C++ 标准库中的一个模板类,用于提供一种机制,允许一个线程在某个时间点产生一个值(或异常),并使其他线程能够等待并获取该值(或异常)。</p>
<p>在你提供的代码中, <code>wsPromise</code> 是一个名为 <code>wsPromise</code> 的对象,它是 <code>std::promise&lt;void&gt;</code> 类型的实例。这意味着它是一个用于产生 <code>void</code> 类型值的 <code>promise</code> 对象。</p>
<p><code>std::promise</code> 类提供了两个主要操作: <code>set_value()</code> 和 <code>set_exception()</code> 。通过调用 <code>set_value()</code> ,可以在 <code>promise</code> 对象上设置一个值(在这种情况下,是 <code>void</code> 类型的值),然后通过调用 <code>get_future()</code> 获得一个与该 <code>promise</code> 相关联的 <code>std::future</code> 对象,其他线程可以通过该 <code>future</code> 对象等待并获取该值。</p>
<p>以下是一个简单的示例,展示了如何使用 <code>std::promise&lt;void&gt;</code> 和相关的类来实现线程间的同步:</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;iostream></span></span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;thread></span></span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;future></span></span></pre></td></tr><tr><td data-num="4"></td><td><pre></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token keyword">void</span> <span class="token function">worker</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>promise<span class="token operator">&lt;</span><span class="token keyword">void</span><span class="token operator">></span><span class="token operator">&amp;</span> promise<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token comment">// 模拟一些耗时的工作</span></pre></td></tr><tr><td data-num="7"></td><td><pre> std<span class="token double-colon punctuation">::</span>this_thread<span class="token double-colon punctuation">::</span><span class="token function">sleep_for</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>chrono<span class="token double-colon punctuation">::</span><span class="token function">seconds</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> </pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token comment">// 工作完成后,设置 promise 的值</span></pre></td></tr><tr><td data-num="10"></td><td><pre> promise<span class="token punctuation">.</span><span class="token function">set_value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="11"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="12"></td><td><pre></pre></td></tr><tr><td data-num="13"></td><td><pre><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="14"></td><td><pre> std<span class="token double-colon punctuation">::</span>promise<span class="token operator">&lt;</span><span class="token keyword">void</span><span class="token operator">></span> wsPromise<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="15"></td><td><pre> std<span class="token double-colon punctuation">::</span>future<span class="token operator">&lt;</span><span class="token keyword">void</span><span class="token operator">></span> wsFuture <span class="token operator">=</span> wsPromise<span class="token punctuation">.</span><span class="token function">get_future</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="16"></td><td><pre> </pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token comment">// 创建一个工作线程,并传递 promise 作为参数</span></pre></td></tr><tr><td data-num="18"></td><td><pre> std<span class="token double-colon punctuation">::</span>thread <span class="token function">workerThread</span><span class="token punctuation">(</span>worker<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span><span class="token function">ref</span><span class="token punctuation">(</span>wsPromise<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="19"></td><td><pre> </pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token comment">// 等待工作线程完成</span></pre></td></tr><tr><td data-num="21"></td><td><pre> wsFuture<span class="token punctuation">.</span><span class="token function">wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="22"></td><td><pre> </pre></td></tr><tr><td data-num="23"></td><td><pre> std<span class="token double-colon punctuation">::</span>cout <span class="token operator">&lt;&lt;</span> <span class="token string">"Worker thread finished."</span> <span class="token operator">&lt;&lt;</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="24"></td><td><pre> </pre></td></tr><tr><td data-num="25"></td><td><pre> workerThread<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="26"></td><td><pre> </pre></td></tr><tr><td data-num="27"></td><td><pre> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="28"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><p>在上述示例中, <code>worker()</code> 函数是一个工作线程执行的函数。它接受一个 <code>std::promise&lt;void&gt;</code> 对象作为参数,并通过调用 <code>set_value()</code> 来设置该 <code>promise</code> 对象的值。主线程使用 <code>get_future()</code> 获取与 <code>promise</code> 对象相关联的 <code>std::future</code> 对象,并使用 <code>wait()</code> 函数等待工作线程完成。一旦工作线程完成并设置了 <code>promise</code> 的值,主线程将继续执行。</p>
<p>需要注意的是, <code>std::promise</code> 和 <code>std::future</code> 提供了一种线程间通信的机制,其中一个线程通过 <code>promise</code> 设置值,而另一个线程通过 <code>future</code> 等待并获取该值。</p>
</li>
<li>
<p><code>std::promise</code> 类中的 <code>set_exception()</code> 函数用于在 <code>promise</code> 对象上设置一个异常,以通知与之关联的 <code>std::future</code> 对象所在的线程。</p>
<p>当某个线程调用 <code>set_exception()</code> 函数并提供一个异常作为参数时,与该 <code>promise</code> 对象关联的 <code>std::future</code> 对象上的等待操作将会收到该异常(通过 <code>std::future</code> 对象的 <code>get()</code> 函数或 <code>wait()</code> 函数调用时抛出)。</p>
<p>以下是一个示例,展示了如何使用 <code>std::promise</code> 的 <code>set_exception()</code> 函数来传递异常:</p>
<figure class="highlight cpp"><figcaption data-lang="C++"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;iostream></span></span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;thread></span></span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;future></span></span></pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;stdexcept></span></span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token keyword">void</span> <span class="token function">worker</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>promise<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">></span><span class="token operator">&amp;</span> promise<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token keyword">try</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token comment">// 模拟一些工作</span></pre></td></tr><tr><td data-num="9"></td><td><pre> std<span class="token double-colon punctuation">::</span>this_thread<span class="token double-colon punctuation">::</span><span class="token function">sleep_for</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>chrono<span class="token double-colon punctuation">::</span><span class="token function">seconds</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="10"></td><td><pre> </pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token comment">// 抛出一个异常</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token keyword">throw</span> std<span class="token double-colon punctuation">::</span><span class="token function">runtime_error</span><span class="token punctuation">(</span><span class="token string">"Something went wrong."</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="13"></td><td><pre> </pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token comment">// 设置 promise 的值(这行代码不会执行)</span></pre></td></tr><tr><td data-num="15"></td><td><pre> promise<span class="token punctuation">.</span><span class="token function">set_value</span><span class="token punctuation">(</span><span class="token number">42</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token comment">// 捕获异常,并通过 promise 设置异常</span></pre></td></tr><tr><td data-num="18"></td><td><pre> promise<span class="token punctuation">.</span><span class="token function">set_exception</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">current_exception</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="19"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="20"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="21"></td><td><pre></pre></td></tr><tr><td data-num="22"></td><td><pre><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="23"></td><td><pre> std<span class="token double-colon punctuation">::</span>promise<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">></span> wsPromise<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="24"></td><td><pre> std<span class="token double-colon punctuation">::</span>future<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">></span> wsFuture <span class="token operator">=</span> wsPromise<span class="token punctuation">.</span><span class="token function">get_future</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="25"></td><td><pre> </pre></td></tr><tr><td data-num="26"></td><td><pre> <span class="token comment">// 创建一个工作线程,并传递 promise 作为参数</span></pre></td></tr><tr><td data-num="27"></td><td><pre> std<span class="token double-colon punctuation">::</span>thread <span class="token function">workerThread</span><span class="token punctuation">(</span>worker<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span><span class="token function">ref</span><span class="token punctuation">(</span>wsPromise<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="28"></td><td><pre> </pre></td></tr><tr><td data-num="29"></td><td><pre> <span class="token keyword">try</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="30"></td><td><pre> <span class="token comment">// 等待工作线程完成</span></pre></td></tr><tr><td data-num="31"></td><td><pre> <span class="token keyword">int</span> result <span class="token operator">=</span> wsFuture<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="32"></td><td><pre> std<span class="token double-colon punctuation">::</span>cout <span class="token operator">&lt;&lt;</span> <span class="token string">"Worker thread finished with result: "</span> <span class="token operator">&lt;&lt;</span> result <span class="token operator">&lt;&lt;</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="33"></td><td><pre> <span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>exception<span class="token operator">&amp;</span> ex<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span></pre></td></tr><tr><td data-num="34"></td><td><pre> std<span class="token double-colon punctuation">::</span>cout <span class="token operator">&lt;&lt;</span> <span class="token string">"Worker thread threw an exception: "</span> <span class="token operator">&lt;&lt;</span> ex<span class="token punctuation">.</span><span class="token function">what</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&lt;&lt;</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span></pre></td></tr><tr><td data-num="35"></td><td><pre> <span class="token punctuation">&#125;</span></pre></td></tr><tr><td data-num="36"></td><td><pre> </pre></td></tr><tr><td data-num="37"></td><td><pre> workerThread<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="38"></td><td><pre> </pre></td></tr><tr><td data-num="39"></td><td><pre> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span></pre></td></tr><tr><td data-num="40"></td><td><pre><span class="token punctuation">&#125;</span></pre></td></tr></table></figure><p>在上述示例中, <code>worker()</code> 函数模拟一个工作线程执行的工作。在这个例子中,工作线程抛出了一个 <code>std::runtime_error</code> 异常,然后通过 <code>set_exception()</code> 函数将异常传递给与 <code>promise</code> 对象关联的 <code>std::future</code> 对象。主线程使用 <code>get()</code> 函数获取 <code>std::future</code> 对象上的值时,如果工作线程抛出了异常, <code>get()</code> 函数将重新抛出该异常,然后可以在主线程中捕获并处理该异常。</p>
<p>总而言之, <code>set_exception()</code> 函数允许在 <code>promise</code> 对象上设置异常,以便将异常传递给与之关联的 <code>std::future</code> 对象所在的线程,从而实现线程间的异常传递和处理。</p>
</li>
<li>
<p><code>std::cin.ignore()</code> 是 C++ 标准库中 <code>std::cin</code> 流的成员函数之一。它的作用是忽略输入流中的字符。</p>
<p><code>std::cin.ignore()</code> 函数通常与 <code>std::cin</code> 结合使用,用于清除输入缓冲区中的字符,以便接下来的输入操作不会受到之前输入的影响。</p>
<p>该函数可以在两种形式下使用:</p>
<ol>
<li><code>std::cin.ignore()</code> :调用函数时不传递参数。它会忽略输入流中的下一个字符,无论是换行符、空格符还是其他字符。</li>
<li><code>std::cin.ignore(n, delim)</code> :调用函数时传递两个参数。其中, <code>n</code> 是要忽略的字符数, <code>delim</code> 是可选的定界符(默认为换行符)。
<ul>
<li>如果提供了 <code>n</code> ,则会忽略输入流中的前 <code>n</code> 个字符。</li>
<li>如果同时提供了 <code>n</code> 和 <code>delim</code> ,则会忽略输入流中的字符,直到遇到定界符 <code>delim</code> 为止。</li>
</ul>
</li>
</ol>
<p>这些函数在某些情况下很有用,例如当需要清除输入缓冲区中的残留字符时,或者在读取不同类型的数据之前需要忽略一些字符。</p>
</li>
<li>
<p>部分 C 语言库,在 c++ 文件中使用需要用 <code>extern &quot;C&quot;&#123;&#125;</code> 的形式包裹起来,否则编译链接时会找不到库中函数的实现,例如 FFmpeg 库中的库:</p>
</li>
</ol>
<pre><code>```C++
extern &quot;C&quot; &#123;
#include &lt;libavcodec/avcodec.h&gt;
#include &lt;libavcodec/packet.h&gt;
#include &lt;libavformat/avformat.h&gt;
&#125;
```
</code></pre>
</content>
<category term="C++" scheme="http://yuanmxc.site/categories/C/" />
<updated>2024-06-02T01:56:41.038Z</updated>
</entry>
<entry>
<id>http://yuanmxc.site/%E9%9A%8F%E7%AC%94/%E7%AC%AC%E4%B8%80%E6%AC%A1%E9%9A%8F%E7%AC%94/</id>
<title>第一次随笔</title>
<link rel="alternate" href="http://yuanmxc.site/%E9%9A%8F%E7%AC%94/%E7%AC%AC%E4%B8%80%E6%AC%A1%E9%9A%8F%E7%AC%94/"/>
<content type="html"><h1 id="起因"><a class="anchor" href="#起因">#</a> 起因</h1>
<p>3.25 晚上整理博客,QQ 上看到一段话,还不错,正好博客弄好了,” 关于 “这部分还不知道放些什么东西。随笔这些写上面感觉还不错,于是开始在博客上写随笔。但是敲来敲去,总觉得哪里有些怪,不自然。看着屏幕上写的东西,总感觉有那么一丝丝奇怪。</p>
<p><strong>逃避</strong> — 差不多就是这样。选择困难症又开始了,博客上要不要 &quot;记录生活&quot;,写写随笔,还是只写技术,写随笔写什么,怎么写。</p>
<h1 id="高中旧物"><a class="anchor" href="#高中旧物">#</a> 高中旧物</h1>
<p>初中高中的时候也有写过一些记录当时所思所想的文字,尤其是高三压力大那时候,晚上猫在被窝打灯写,虽然大部分是和 ys 有关,但是也包含了自己当时的所思所想,也给了自己不少坚持下去的动力。</p>
<p>但毕业以后,人生开始踏入新的阶段,整理之前的旧物时又开始选择。那时的自己喜欢简约,什么东西都整整齐齐,有条理,同时也不想无关的东西来占用自己的空间和时间。” 断舍离 “践行的很好,包括现在也是。</p>
<p>“长时间用不到的东西扔掉就好了,即使未来某一天想用到它,也就是那么很短的一段时间。想回忆的时候感触万千,但部分时间他们都是无用之物 “。就是这种想法。我现在也觉得没错。三年过去,对于那些记录,也就现在有那么一点” 如果没有扔掉,现在看看也不不错 “的想法,其他时间根本就没想。</p>
<h1 id="写吧"><a class="anchor" href="#写吧">#</a> 写吧</h1>
<p>写随笔在自己看来其实一件很好的事情,鼓励自己,反省自己,记录生活,,但是 “有写他们的时间我为什么不去做些其他的事情呢” 这种想法总会占据上风。事实也确实如此,比如现在写这篇文章就要花不少时间。</p>
<p>正在纠结的时候学弟过来给我看了他昨晚写的博客,也是随笔,简单的记录生活,简单的排版,简单的描述,看着还不错,是自己犹犹豫豫不敢写的东西。</p>
<p>看完后又去看了一下他的友链中一个人的博客。是 23 届一个学前端的女生,写了几篇博客记录自己的生活,文笔也不错,写的很好,一连看了几篇,虽然所有图片都无法查看(应该是图床没配好)但是让我看的心情变得不错。也下定决心开是写些东西。</p>
<h1 id="后谈"><a class="anchor" href="#后谈">#</a> 后谈</h1>
<p>其实写这些花费时间是肯定的,但不一定就是” 浪费 “,写或者不写而引发的一系列反应会导致什么结果。写了这些可能让自己心情变好?影响学习效率?影响心态?时间总是要花费的,无非就是这段时间花费是不是花在你想做的事情上。如果写随笔是想做的事情,那也就是不用犹豫了。</p>
<p>以后有时间,想写了就写一些,随时、随地、随便。也不用太在乎排版啊,观感啊这些。始终觉得写东西首先是给自己看的,其次才是给别人看。</p>
<p>修博客的时候不知道写什么话放在首页好,后来发现自己用了很久的 QQ 签名不就很不错嘛:</p>
<p><strong>不乱于心,不困于情;不畏将来,不念过往。</strong></p>
<p>是丰子恺先生写的。顺带查了一下,这句话是丰子恺先生《无宠不惊过一生》的一句诗。</p>
<p>全诗如下:</p>
<p><em>不乱于心,不困于情;不畏将来,不念过往。如此,安好!</em><br />
<em> 深谋若谷,深交若水;深明大义,深悉小节,已然,静舒!</em><br />
<em> 善宽以怀,善感以恩;善博以浪,善精以业。这般。最佳!</em><br />
<em> 勿感于时,勿伤于怀;勿耽美色,勿沉虚妄。从今,进取!</em><br />
<em> 无愧于天,无愧于地。无怍于人,无惧于鬼。这样。人生!</em></p>
<p>写的是真不错啊。记下记下,后面还想开一些好词、好句之类的地方,收藏一下,初高中的东西都丢了,那时候因为要写作文,” 顺带 “收集了不少自己觉得不错的好词、好诗、好句,可惜都遗失了,不过现在开始,慢慢找回来吧。</p>
<p>打字打的手疼,好像还没一次性连续打这么多字。估计还有很多错字,已经不想再检查了,今天先到这里吧。</p>
<p>下面是那天晚上写的东西,也就先这么放着:</p>
<p>也不知道这里该写些什么,感觉有很多想写的,又感觉没什么写的。就瞎写得了,随性一点也不错。想起啥写啥。“以后会优化”</p>
<blockquote>
<p>三年后,你结婚了,下班回家看着你不爱的人,烦得吃不下饭,床都不愿意上,话也不想说,你会不会后悔曾经太听家人的话;</p>
<p>三年后,你结婚了,下班回家看着你当初奋不顾身要嫁的人,对你很是厌烦,只知道打游戏,话都懒得跟你说,再看看满屋的狼藉,吵闹的孩子,没洗的碗筷,他甚至家都不愿意回,你会不会后悔曾经不听家人的话;</p>
<p>三年后,你未婚,看见朋友都幸福美满,你流露出羡慕的眼神,可又看到他们为了房贷,车贷,孩子的费用,柴米油盐的平淡和枯燥锁纠缠,你庆幸自由且随意;</p>
<p>三年后,你仍没有结婚,看到别人家烟花满巷,内心的孤独和失落油然而生,对未来的迷茫无从安放。那一刻你会不会觉得自己是芸芸众生中最普通的一员,你是否会后悔当初决定不结婚;</p>
<p>巷子里的猫很自由,却没有归宿,围墙里的狗有归宿,终身都得低头,人生这道选择题,怎么选都会有遗憾,人总以为自己没有过的路上开满了鲜花,凡事看的太透,人间便无趣了,该来的都回来,该走的也都会走。别抗拒,别挽留,太注重细节的人注定不会快乐。</p>
</blockquote>
<p>QQ 看点偶然看到的。例子终究是例子,你自己的生活什么样不是别人说出来的。有人陪或者三年后自己差不多也该到结婚的时候了吧,人生即将打下一个基调。婚可能还是要结的,孩子可能还是要要的,自己的想法应该还没到扭转这个路线的能力?决心?自己也说不清。“传统路线” 还是自由选择,就交给将来的自己去抉择把。至少现在觉得养孩子,还贷还不是自己想要的生活。不喜欢背负着太多压力,不喜欢没有选择,不喜欢” 不得不 “,喜欢” 所做的一切都是因为自己原意去做,想去做,想去过什么生活,想成为什么样的人 “。未来的事情交给未来就好了,未来总会成为现在的。</p>
<p>最后几句话和前面关系不大吧。“凡事看的太透,人间便无趣了” 这话怎么感觉说的这么像自己的状态。很多事情都没什么大兴趣,“无所谓”“都行”。</p>
<p>有些后悔初中高中写的东西没保存了,高三末写的那个本子啊,就,之前的心态好想是对过去的没什么可留恋的。</p>
</content>
<category term="随笔" scheme="http://yuanmxc.site/categories/essay/" />
<updated>2024-03-26T12:51:51.467Z</updated>
</entry>
<entry>
<id>http://yuanmxc.site/Archlinux/ArchLinux%E4%BD%BF%E7%94%A8%E8%AE%B0%E5%BD%95/</id>
<title>ArchLinux使用记录</title>
<link rel="alternate" href="http://yuanmxc.site/Archlinux/ArchLinux%E4%BD%BF%E7%94%A8%E8%AE%B0%E5%BD%95/"/>
<content type="html"><h2 id="零"><a class="anchor" href="#零">#</a> 零</h2>
<p>强烈推荐阅读:<span class="exturl" data-url="aHR0cHM6Ly9hcmNobGludXhzdHVkaW8uZ2l0aHViLmlvL0FyY2hMaW51eFR1dG9yaWFsLyMvP2lkPWFyY2gtbGludXgtJUU1JUFFJTg5JUU4JUEzJTg1JUU0JUJEJUJGJUU3JTk0JUE4JUU2JTk1JTk5JUU3JUE4JThCLWFyY2h0dXRvcmlhbC1hcmNoLWxpbnV4LXN0dWRpbw==">Arch Linux 安装使用教程</span> 和 <span class="exturl" data-url="aHR0cHM6Ly9hcmNobGludXhzdHVkaW8uZ2l0aHViLmlvL0FyY2hMaW51eFR1dG9yaWFsLyMvP2lkPWFyY2gtbGludXgtJUU1JUFFJTg5JUU4JUEzJTg1JUU0JUJEJUJGJUU3JTk0JUE4JUU2JTk1JTk5JUU3JUE4JThCLWFyY2h0dXRvcmlhbC1hcmNoLWxpbnV4LXN0dWRpbw==">archlinux 简明指南</span> 。 这两本书都是内容非常详尽的 Arch Linux 安装和使用教程,包括 Arch Linux 安装、基本配置、日产使用、常用软件安装等内容,可以帮助初学者解决很多问题。</p>
<p>笔者本人使用笔记本单固态应硬盘安装 windows10 + ArchLinux 双系统,推荐按照 <span class="exturl" data-url="aHR0cHM6Ly9hcmNobGludXhzdHVkaW8uZ2l0aHViLmlvL0FyY2hMaW51eFR1dG9yaWFsLyMvP2lkPWFyY2gtbGludXgtJUU1JUFFJTg5JUU4JUEzJTg1JUU0JUJEJUJGJUU3JTk0JUE4JUU2JTk1JTk5JUU3JUE4JThCLWFyY2h0dXRvcmlhbC1hcmNoLWxpbnV4LXN0dWRpbw==">archlinux 简明指南</span> 的安装步骤进行安装。</p>
<p>安装过程需要注意:</p>
<ol>
<li>
<p>清楚你即将使用的命令做了什么,不要一味回车回车...</p>
</li>
<li>
<p>按照教程的大纲,分模块进行,分清每一块做了什么,不要一行一行,遇见一个敲一个,先通读知晓这一块是做什么之后,返回来按照自己需要的去做。</p>
</li>
<li>
<p>不要过分地 “多线程” 操作试图节省时间,稳中前进,不出错就是最快的。</p>
</li>
<li>
<p>仔细对照好输入的命令是否正确,确认每个命令的结果是否符合预期。</p>
<p><span class="exturl" data-url="aHR0cHM6Ly9iYnMuYXJjaGxpbnV4Y24ub3JnL2luZGV4LnBocA==">Arclinux 中文论坛</span> 众多 Archlinux 使用者汇集的地方,同时有着较为官方的信息和软件包,很多问题可以在这里解决。</p>
</li>
</ol>
<h2 id="部分命令记录"><a class="anchor" href="#部分命令记录">#</a> 部分命令记录</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> <span class="token function">fdisk</span> <span class="token parameter variable">-l</span> <span class="token comment"># 查看磁盘和分区信息</span></pre></td></tr><tr><td data-num="2"></td><td><pre>df-h <span class="token comment"># 显示文件系统磁盘空间使用情况</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">sudo</span> <span class="token function">umount</span> /dev/sdX <span class="token comment"># 卸载 U 盘,“/dev/sdX” 为你要卸载的 U 盘设备名称。</span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token function">sudo</span> mkfs.vfat /dev/sdX <span class="token comment"># 将 U 盘格式化为 FAT32 文件系统 /</span></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token function">printenv</span> <span class="token comment"># 查看所有的环境变量</span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token builtin class-name">echo</span> <span class="token operator">&amp;</span><span class="token environment constant">PATH</span> <span class="token comment"># 查看特定环境变量的值(echo $http_proxy)</span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token builtin class-name">export</span> <span class="token assign-left variable">http_proxy</span><span class="token operator">=</span><span class="token string">"http://127.0.0.1:7890"</span> <span class="token comment"># 设置代理服务器,设置 http_proxy 和 https_proxy 环境变量</span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token builtin class-name">export</span> <span class="token assign-left variable">https_proxy</span><span class="token operator">=</span><span class="token string">"http://127.0.0.1:7890"</span></pre></td></tr></table></figure><p>以下命令需要安装后才能使用:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>tree <span class="token parameter variable">-A</span> 使用ASNI绘图字符显示树状图而非以ASCII字符组合</pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token parameter variable">-C</span> 使用颜色区分文件类型</pre></td></tr><tr><td data-num="3"></td><td><pre> <span class="token parameter variable">-N</span> 支持显示中文字符</pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token parameter variable">-a</span> 显示隐藏文件<span class="token punctuation">(</span>以.开头<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token parameter variable">-d</span> 只显示目录</pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token parameter variable">-h</span> 使用人易读的单位显示文件大小</pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token parameter variable">-L</span> <span class="token punctuation">[</span>num<span class="token punctuation">]</span> 指定显示的最大深度</pre></td></tr></table></figure><p>##Pacman 包管理:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Syu</span> <span class="token comment"># 升级系统</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-S</span> package_name <span class="token comment"># 安装软件包</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Syu</span> package_name <span class="token comment"># 升级系统并安装软件包,ArchLinux 不支持部分升级,建议用此命令先升级再安装</span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Syyu</span> <span class="token comment"># 升级系统 yy 标记强制刷新 u 标记升级动作</span></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Ss</span> package_name <span class="token comment"># 搜索包含相关内容的软件包</span></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-R</span> package_name <span class="token comment"># 删除软件包</span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Qi</span> package_name <span class="token comment"># 查看软件包信息 </span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Q</span> <span class="token comment"># 查看安装的软件包 </span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Rs</span> package_name <span class="token comment"># 删除软件包,及其所有没有被其他已安装软件包使用的依赖包</span></pre></td></tr><tr><td data-num="10"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Si</span> package_name <span class="token comment"># 从数据库中搜索软件包的信息</span></pre></td></tr><tr><td data-num="11"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Qdt</span> <span class="token comment"># 找出孤立包 Q 为查询本地软件包数据库 d 标记依赖包 t 标记不需要的包 dt 合并标记孤立包</span></pre></td></tr><tr><td data-num="12"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Rs</span> <span class="token variable"><span class="token variable">$(</span>pacman <span class="token parameter variable">-Qtdq</span><span class="token variable">)</span></span> <span class="token comment"># 删除孤立软件包</span></pre></td></tr><tr><td data-num="13"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-U</span> abc.pkg.tar.gz <span class="token comment"># 安装下载的 abc 包,或新编译的本地 abc 包</span></pre></td></tr><tr><td data-num="14"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Fy</span> <span class="token comment"># 更新命令查询文件列表数据库</span></pre></td></tr><tr><td data-num="15"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-F</span> xxx <span class="token comment"># 当不知道某个命令属于哪个包时,用来查询某个 xxx 命令属于哪个包</span></pre></td></tr><tr><td data-num="16"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Sc</span> <span class="token comment"># 清理没有安装的所有缓存包,和没有被使用的同步数据库</span></pre></td></tr><tr><td data-num="17"></td><td><pre></pre></td></tr><tr><td data-num="18"></td><td><pre>yay <span class="token parameter variable">-Syu</span> <span class="token comment"># 升级官方和 AUR 的软件包,包括 pacman, -syyu 强制升级</span></pre></td></tr><tr><td data-num="19"></td><td><pre>yay <span class="token parameter variable">-S</span> abc <span class="token comment"># 安装 abc 包</span></pre></td></tr><tr><td data-num="20"></td><td><pre>yay <span class="token parameter variable">-Ss</span> abc <span class="token operator">|</span> <span class="token function">grep</span> 已安装 <span class="token comment"># 搜索已安装且包含 abc 的包</span></pre></td></tr><tr><td data-num="21"></td><td><pre>yay <span class="token parameter variable">-R</span> 包名 <span class="token comment"># 删除软件包 (不包括前后缀,版本号)</span></pre></td></tr><tr><td data-num="22"></td><td><pre><span class="token function">sudo</span> <span class="token function">rm</span> /var/lib/pacman/db.lck <span class="token comment"># 删除 /var/lib/pacman/db.lck 锁</span></pre></td></tr></table></figure><h2 id="系统服务的操作与介绍"><a class="anchor" href="#系统服务的操作与介绍">#</a> 系统服务的操作与介绍</h2>
<p>Linux 系统中运行着各种服务,你需要掌握查询,变更服务状态的方式。同时对创建服务最好也有大致的了解。这里讲述命令 <code>systemctl</code> 的用法。以 dhcpcd 为例</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>systemctl start dhcpcd <span class="token comment"># 启动服务</span></pre></td></tr><tr><td data-num="2"></td><td><pre>systemctl stop dhcpcd <span class="token comment"># 停止服务</span></pre></td></tr><tr><td data-num="3"></td><td><pre>systemctl restart dhcpcd <span class="token comment"># 重启服务</span></pre></td></tr><tr><td data-num="4"></td><td><pre>systemctl reload dhcpcd <span class="token comment"># 重新加载服务以及它的配置文件</span></pre></td></tr><tr><td data-num="5"></td><td><pre>systemctl status dhcpcd <span class="token comment"># 查看服务状态</span></pre></td></tr><tr><td data-num="6"></td><td><pre>systemctl <span class="token builtin class-name">enable</span> dhcpcd <span class="token comment"># 设置开机启动服务</span></pre></td></tr><tr><td data-num="7"></td><td><pre>systemctl <span class="token builtin class-name">enable</span> <span class="token parameter variable">--now</span> dhcpcd <span class="token comment"># 设置服务为开机启动并立即启动这个单元:</span></pre></td></tr><tr><td data-num="8"></td><td><pre>systemctl disable dhcpcd <span class="token comment"># 取消开机自动启动</span></pre></td></tr><tr><td data-num="9"></td><td><pre>systemctl daemon-reload dhcpcd <span class="token comment"># 重新载入 systemd 配置 扫描新增或变更的服务单元 不会重新加载变更的配置 加载变更的配置用 reload</span></pre></td></tr></table></figure><h2 id="换源-阿里云"><a class="anchor" href="#换源-阿里云">#</a> 换源 - 阿里云</h2>
<p>编辑文件 <code>/etc/pacman.d/mirrorlist</code> :</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> <span class="token function">vim</span> /etc/pacman.d/mirrorlist</pre></td></tr></table></figure><p>在镜像源列表最顶端添加:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>Server <span class="token operator">=</span> http://mirrors.aliyun.com/archlinux/<span class="token variable">$repo</span>/os/<span class="token variable">$arch</span></pre></td></tr></table></figure><blockquote>
<p>参考:<span class="exturl" data-url="aHR0cHM6Ly9kZXZlbG9wZXIuYWxpeXVuLmNvbS9taXJyb3IvYXJjaGxpbnV4Y24/c3BtPWEyYzZoLjEzNjUxMTAyLjAuMC4zZTIyMWIxMU5jOFVwWQ==">阿里云开发者社区 &gt; 镜像站 &gt; archlinuxcn</span></p>
</blockquote>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Syy</span> <span class="token operator">&amp;&amp;</span> <span class="token function">sudo</span> pacman <span class="token parameter variable">-S</span> archlinuxcn-keyring <span class="token comment"># 安装 archlinuxcn-keyring 包导入 GPG key</span></pre></td></tr></table></figure><h2 id="安装yay"><a class="anchor" href="#安装yay">#</a> 安装 yay</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-S</span> yay</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token comment">#安装完成后再次更新</span></pre></td></tr><tr><td data-num="3"></td><td><pre>yay <span class="token parameter variable">-Syyu</span> <span class="token operator">&amp;&amp;</span> yay <span class="token parameter variable">-Sys</span></pre></td></tr></table></figure><h2 id="常见问题及其解决"><a class="anchor" href="#常见问题及其解决">#</a> 常见问题及其解决</h2>
<ul>
<li>
<p>使用 yay 命令时报错:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>搜索 AUR 时出错: response decoding failed: invalid character <span class="token string">'&lt;'</span> looking <span class="token keyword">for</span></pre></td></tr></table></figure><ul>
<li>解决:</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>yay <span class="token parameter variable">--aururl</span> <span class="token string">"https://aur.archlinux.org"</span> <span class="token parameter variable">--save</span></pre></td></tr></table></figure></li>
<li>
<p>Telegram 无法登陆:</p>
<ul>
<li>解决:<br />
SETTING 中添加地址,使用代理,port 选择代理所使用端口号。</li>
</ul>
</li>
<li>
<p>连接显示器无法使用:</p>
<ul>
<li>解决:<br />
根据<span class="exturl" data-url="aHR0cHM6Ly9hcmNobGludXhzdHVkaW8uZ2l0aHViLmlvL0FyY2hMaW51eFR1dG9yaWFsLyMv"> Linux 安装使用教程</span>中<strong>显卡驱动</strong>所描述进行即可。</li>
</ul>
</li>
<li>
<p>VSCode 无法唤出外部终端:</p>
<ul>
<li>解决:<br />
<code>.vscode</code> 文件中设置启用外部终端,在 <code>settings.json</code> 文件中加入 &quot;terminal.external.linuxExec&quot;: &quot;/usr/bin/konsole&quot;, &quot;&quot; 内指要调用的终端 bin/konsole。</li>
</ul>
</li>
<li>
<p>在升级系统(syu)时,出现以下内容:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>错误:python-markdown: 来自 <span class="token string">"Caleb Maclennan &lt;alerque@archlinux.org>"</span> 的签名是勉强信任的</pre></td></tr><tr><td data-num="2"></td><td><pre>:: 文件 /var/cache/pacman/pkg/python-markdown-3.3.6-1-any.pkg.tar.zst 已损坏 <span class="token punctuation">(</span>无效或已损坏的软件包 <span class="token punctuation">(</span>PGP 签名<span class="token punctuation">))</span>.</pre></td></tr><tr><td data-num="3"></td><td><pre>打算删除吗? <span class="token punctuation">[</span>Y/n<span class="token punctuation">]</span> </pre></td></tr><tr><td data-num="4"></td><td><pre>错误:trash-cli: 来自 <span class="token string">"Alexander Epaneshnikov &lt;alex19ep@archlinux.org>"</span> 的签名是勉强信任的</pre></td></tr><tr><td data-num="5"></td><td><pre>:: 文件 /var/cache/pacman/pkg/trash-cli-0.21.10.24-1-any.pkg.tar.zst 已损坏 <span class="token punctuation">(</span>无效或已损坏的软件包 <span class="token punctuation">(</span>PGP 签名<span class="token punctuation">))</span>.</pre></td></tr><tr><td data-num="6"></td><td><pre>打算删除吗? <span class="token punctuation">[</span>Y/n<span class="token punctuation">]</span> </pre></td></tr><tr><td data-num="7"></td><td><pre>错误:无法提交处理 <span class="token punctuation">(</span>无效或已损坏的软件包<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="8"></td><td><pre>发生错误,没有软件包被更新。</pre></td></tr></table></figure><ul>
<li>
<p>解决:</p>
<p>终端输入: <code>sudo pacman-key --init &amp;&amp; sudo pacman-key --populate &amp;&amp; sudo pacman -Syyu</code></p>
<p>可能的方法: <code>sudo pacman -S archlinux-keyring</code></p>
</li>
</ul>
</li>
</ul>
<h2 id="使用docker"><a class="anchor" href="#使用docker">#</a> 使用 Docker</h2>
<ol>
<li>
<p>安装:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-S</span> <span class="token function">docker</span> <span class="token comment"># 安装 Docker -Ss 搜索 Docker 软件包</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">sudo</span> systemctl <span class="token builtin class-name">enable</span> docker.service <span class="token comment"># 开启 Docker 开机自启动服务</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">sudo</span> systemctl start docker.service <span class="token comment"># 启动 Docker 服务</span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token comment"># 安装好 docker 后自动建立了 docker 组,不需要自己添加 docker 组,只需要把当前工作用户加入 docker 组即可</span></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token function">sudo</span> gpasswd <span class="token parameter variable">-a</span> <span class="token environment constant">$USER</span> <span class="token function">docker</span> <span class="token comment"># 把工作用户加入 Docker 组,避免使用 root 账号工作</span></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token comment">#重启系统生效</span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token function">sudo</span> systemctl disable docker.service <span class="token comment"># 关闭开机自启动服务</span></pre></td></tr></table></figure></li>
<li>
<p>获取镜像:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">docker</span> pull archlinux <span class="token comment"># 下载镜像</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">docker</span> image <span class="token function">ls</span> <span class="token comment"># 列出镜像列表</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">docker</span> <span class="token function">ps</span> <span class="token parameter variable">-a</span> <span class="token comment"># 列出容器列表</span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token function">docker</span> run <span class="token parameter variable">-it</span> archlinux /bin/bash <span class="token comment"># 用所给镜像启动一个新的容器</span></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token function">docker</span> run <span class="token parameter variable">--rm</span> <span class="token parameter variable">-it</span> <span class="token parameter variable">--net</span><span class="token operator">=</span>host gpt-academic <span class="token comment"># 用所给镜像启动一个新的容器</span></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token function">docker</span> <span class="token builtin class-name">exec</span> <span class="token parameter variable">-it</span> <span class="token operator">&lt;</span>CONTAINER_NAME<span class="token operator">></span> <span class="token function">bash</span> <span class="token comment"># 进入一个正在运行的 docker (在容器内部创建一个子进程)</span></pre></td></tr><tr><td data-num="7"></td><td><pre><span class="token function">docker</span> stop <span class="token punctuation">[</span>contaionerID<span class="token punctuation">]</span> <span class="token comment"># 终止镜像</span></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token function">docker</span> rmi <span class="token variable"><span class="token variable">$(</span><span class="token function">docker</span> images <span class="token parameter variable">-q</span><span class="token variable">)</span></span> <span class="token comment"># 删除所有镜像</span></pre></td></tr><tr><td data-num="9"></td><td><pre><span class="token function">docker</span> stop <span class="token variable"><span class="token variable">$(</span><span class="token function">docker</span> <span class="token function">ps</span> <span class="token parameter variable">-aq</span><span class="token variable">)</span></span> <span class="token comment"># 停止所有容器</span></pre></td></tr><tr><td data-num="10"></td><td><pre><span class="token function">docker</span> container <span class="token function">rm</span> <span class="token punctuation">[</span>contaionerID<span class="token punctuation">]</span> <span class="token comment"># 删除一个处于终止状态的容器</span></pre></td></tr><tr><td data-num="11"></td><td><pre><span class="token function">docker</span> container <span class="token function">rm</span> <span class="token variable"><span class="token variable">$(</span><span class="token function">docker</span> images <span class="token parameter variable">-q</span><span class="token variable">)</span></span> <span class="token comment"># 删除所有容器</span></pre></td></tr></table></figure></li>
<li>
<p>配置镜像:</p>
<p>启动镜像,配置初始开发环境,安装了一些包(可能有些没有用),</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">docker</span> run <span class="token parameter variable">-t</span> <span class="token parameter variable">-i</span> archlinux /bin/bash <span class="token comment"># 启动镜像</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token comment"># 在 docker 内输入以下内容</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'1i Server = http://mirrors.aliyun.com/archlinux/$repo/os/$arch'</span> /etc/pacman.d/mirrorlist <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'1i Server = https://mirrors.tencent.com/archlinux/$repo/os/$arch'</span> /etc/pacman.d/mirrorlist <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'$i [archlinuxcn]'</span> /etc/pacman.conf <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'$i SigLevel = TrustAll'</span> /etc/pacman.conf <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'$i Server = https://repo.archlinuxcn.org/$arch'</span> /etc/pacman.conf <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token parameter variable">-r</span> <span class="token string">'s/^NoExtract\s*=\s*.*/# \0/g'</span> /etc/pacman.conf <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Syyu</span> <span class="token parameter variable">--noconfirm</span> <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="10"></td><td><pre> <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Sy</span> <span class="token parameter variable">--noconfirm</span> archlinuxcn-keyring <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Su</span> --noconfirm<span class="token punctuation">\</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Syy</span> <span class="token parameter variable">--noconfirm</span> <span class="token function">git</span> <span class="token function">vim</span> neovim <span class="token function">zsh</span> oh-my-zsh-git jdk-openjdk jdk8-openjdk jdk11-openjdk <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="12"></td><td><pre> maven yay <span class="token function">zsh</span> python3 go nodejs <span class="token function">npm</span> <span class="token function">yarn</span> tmux python2 zsh-autosuggestions zsh-syntax-highlighting <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="13"></td><td><pre> zsh-theme-powerlevel10k ranger python-pip python-neovim wl-clipboard fzf ripgrep man-db <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="14"></td><td><pre> gcc clang base-devel wqy-zenhei noto-fonts-cjk <span class="token function">wget</span> <span class="token function">unzip</span> thefuck <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">ln</span> <span class="token parameter variable">-sf</span> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Scc</span> <span class="token parameter variable">--noconfirm</span> <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="17"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">rm</span> <span class="token parameter variable">-rf</span> /var/lib/pacman/sync/* /var/cache/pacman/pkg/* <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="18"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">echo</span> <span class="token string">""</span> <span class="token operator">></span> /var/log/pacman.log</pre></td></tr></table></figure><p>精简版本:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'1i Server = http://mirrors.aliyun.com/archlinux/$repo/os/$arch'</span> /etc/pacman.d/mirrorlist <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'1i Server = https://mirrors.tencent.com/archlinux/$repo/os/$arch'</span> /etc/pacman.d/mirrorlist <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="3"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'$i [archlinuxcn]'</span> /etc/pacman.conf <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="4"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'$i SigLevel = TrustAll'</span> /etc/pacman.conf <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="5"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token string">'$i Server = https://repo.archlinuxcn.org/$arch'</span> /etc/pacman.conf <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="6"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">sed</span> <span class="token parameter variable">-i</span> <span class="token parameter variable">-r</span> <span class="token string">'s/^NoExtract\s*=\s*.*/# \0/g'</span> /etc/pacman.conf <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="7"></td><td><pre> <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Syyu</span> <span class="token parameter variable">--noconfirm</span> <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="8"></td><td><pre> <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Sy</span> <span class="token parameter variable">--noconfirm</span> archlinuxcn-keyring <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Su</span> --noconfirm<span class="token punctuation">\</span></pre></td></tr><tr><td data-num="9"></td><td><pre> <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Syy</span> <span class="token parameter variable">--noconfirm</span> <span class="token function">git</span> <span class="token function">vim</span> neovim <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="10"></td><td><pre> maven yay go <span class="token function">npm</span> <span class="token function">yarn</span> tmux <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="11"></td><td><pre> ranger python-pip python-neovim wl-clipboard fzf ripgrep man-db <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="12"></td><td><pre> gcc clang base-devel wqy-zenhei noto-fonts-cjk <span class="token function">wget</span> <span class="token function">unzip</span> thefuck <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="13"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">ln</span> <span class="token parameter variable">-sf</span> /usr/share/zoneinfo/Asia/Shanghai /etc/localtime <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="14"></td><td><pre> <span class="token operator">&amp;&amp;</span> pacman <span class="token parameter variable">-Scc</span> <span class="token parameter variable">--noconfirm</span> <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="15"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token function">rm</span> <span class="token parameter variable">-rf</span> /var/lib/pacman/sync/* /var/cache/pacman/pkg/* <span class="token punctuation">\</span></pre></td></tr><tr><td data-num="16"></td><td><pre> <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">echo</span> <span class="token string">""</span> <span class="token operator">></span> /var/log/pacman.log</pre></td></tr></table></figure></li>
<li>
<p>配置 vscode:</p>
<p>下载插件:Remote Development Pack(包含 Remote-Containers),Docker。打开插件,在 CONTAINERS 中右键 Attach Visual Studio Code,在 vscode 中运行了镜像,重新安装一些扩展,当作一个新的 archlinux 一样使用。</p>
</li>
<li>
<p>容器和本地间的文件传输:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">docker</span> <span class="token function">ps</span> <span class="token parameter variable">-a</span> <span class="token comment"># 获得容器 ID</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">docker</span> <span class="token function">cp</span> 本地文件路径 ID全称:容器路径 <span class="token comment"># 本地文件复制到容器</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">docker</span> <span class="token function">cp</span> ID全称:容器文件路径 本地路径 <span class="token comment"># 容器文件复制到本地</span></pre></td></tr></table></figure></li>
</ol>
<h2 id="typorapicgogithub图床"><a class="anchor" href="#typorapicgogithub图床">#</a> Typora+PicGo+Github 图床</h2>
<p>整体遵循:<span class="exturl" data-url="aHR0cHM6Ly9qdWVqaW4uY24vcG9zdC82ODQ0OTA0MTM3NDA3MDg2NjAwI2hlYWRpbmctOA==">https://juejin.cn/post/6844904137407086600#heading-8</span></p>
<ol>
<li>创建 GIthub 仓库并创建 Token 并复制</li>
<li>下载 PicGo(app)并配置,包括时间戳命名,选择 github 图床,仓库名,分支用 main,设定 Token</li>
<li>下载并配置 node.js</li>
<li>配置 Typora 并测试图床</li>
</ol>
<h3 id="编译安装从-github-下载的源码"><a class="anchor" href="#编译安装从-github-下载的源码">#</a> 编译安装从 GitHub 下载的源码</h3>
<ol>
<li>
<p>执行以下命令,生成 Makefile 文件:</p>
<p><code>./autogen.sh</code></p>
</li>
<li>
<p>如果下载的源代码中已经包含了 Makefile 文件,则可以跳过此步骤。</p>
</li>
<li>
<p>执行以下命令,配置编译选项:</p>
<p><code>./configure</code></p>
<p>configure 脚本会检查系统环境和依赖库,并生成 Makefile 文件。可以通过指定不同的选项来定制编译过程。</p>
<p>例如,可以使用 --prefix 选项指定安装目录,使用 --enable-shared 选项生成共享库等。</p>
</li>
<li>
<p>执行以下命令,开始编译:</p>
<p><code>make</code></p>
<p>这个命令会编译源代码,并生成可执行文件或共享库等。</p>
</li>
<li>
<p>执行以下命令,安装编译好的文件:</p>
</li>
<li>
<p><code>sudo make install</code></p>
<p>这个命令会将编译好的文件安装到系统中,通常是 /usr/local 目录。 如果在执行 configure 或 make 命令时遇到了错误,可以根据错误信息进行调整。通常情况下,错误信息会提示缺少依赖库或者系统环境不兼容等问题。</p>
</li>
</ol>
<h2 id="安装deb包"><a class="anchor" href="#安装deb包">#</a> 安装 deb 包</h2>
<ol>
<li>使用 yay 安装 debtap。 <code>yay -S debtap</code></li>
<li>升级的 debtap。 <code>sudo debtap -U</code></li>
<li>转换 deb 包,生成一个 <code>yourfile.zst</code> 文件。 <code>sudo debtap yourfile.deb</code> (接两次回车)</li>
<li>安装转换后的包。 <code>sudo pacman -U yourfile.zst</code></li>
</ol>
<h2 id="压缩文件"><a class="anchor" href="#压缩文件">#</a> 压缩文件</h2>
<ul>
<li><code>-c</code> :生成一个新的归档文件</li>
<li><code>-f</code> :输出到文件中,</li>
<li><code>-z</code> &amp; <code>-j</code> :将 tar 压缩成 gzip 和 bzip2 格式。</li>
<li><code>archive</code> :压缩文件的名称</li>
<li><code>/path/to/folder</code> :要压缩的文件夹的路径。</li>
</ul>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token comment"># 将文件夹压缩成 .tar 文件:</span></pre></td></tr><tr><td data-num="2"></td><td><pre>copy codetar <span class="token parameter variable">-cf</span> archive.tar /path/to/folder</pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token comment"># 将文件夹压缩成 .tar.gz 文件:</span></pre></td></tr><tr><td data-num="4"></td><td><pre>copy codetar <span class="token parameter variable">-czf</span> archive.tar.gz /path/to/folder</pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token comment"># 将文件夹压缩成 .tar.bz2 文件:</span></pre></td></tr><tr><td data-num="6"></td><td><pre>copy codetar <span class="token parameter variable">-cjf</span> archive.tar.bz2 /path/to/folder</pre></td></tr></table></figure><h2 id="安装qq"><a class="anchor" href="#安装qq">#</a> 安装 QQ</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>yay <span class="token parameter variable">-Ss</span> linuxqq <span class="token comment"># 在 AUR 查找 linuxQQ </span></pre></td></tr><tr><td data-num="2"></td><td><pre>yay <span class="token parameter variable">-S</span> linuxqq <span class="token comment"># 从 AUR 安装 linuxqq</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Rns</span> linuxqq <span class="token comment"># 删除 linuxqq 及不再需要的依赖</span></pre></td></tr></table></figure><h3 id="登陆后闪退的可能解决办法"><a class="anchor" href="#登陆后闪退的可能解决办法">#</a> 登陆后闪退的可能解决办法:</h3>
<p>删除 <code>~/.config/QQ</code> 下的所有文件,重启 QQ 进行登陆并在设置里关闭 QQ 自己的更新。</p>
<p>其他问题请自行在 Google 或者在<span class="exturl" data-url="aHR0cHM6Ly9iYnMuYXJjaGxpbnV4Y24ub3JnL2luZGV4LnBocA=="> Arch 中文社区</span>寻找解决方案</p>
<h2 id="安装-fcitx5及中文输入法"><a class="anchor" href="#安装-fcitx5及中文输入法">#</a> 安装 fcitx5 及中文输入法</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-S</span> fcitx5-im </pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-S</span> fcitx5-chinese-addons fcitx5-rime</pre></td></tr></table></figure><p><code>sudo vim /etc/environment</code> ,添加如下内容,之后重启输入法:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token assign-left variable">GTK_IM_MODULE</span><span class="token operator">=</span>fcitx</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token assign-left variable">QT_IM_MODULE</span><span class="token operator">=</span>fcitx</pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token assign-left variable"><span class="token environment constant">XMODIFIERS</span></span><span class="token operator">=</span>@im<span class="token operator">=</span>fcitx</pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token assign-left variable">SDL_IM_MODULE</span><span class="token operator">=</span>fcitx</pre></td></tr></table></figure><p>在设置中找到输入法,添加输入法,选拼音</p>
<h3 id="中文标点消失"><a class="anchor" href="#中文标点消失">#</a> 中文标点消失:</h3>
<ul>
<li>
<p>编辑~/.config/fcitx/data/punc.mb.zh_CN,自行查找</p>
</li>
<li>
<p>[ctrl+.]</p>
</li>
</ul>
<h2 id="安装zsh"><a class="anchor" href="#安装zsh">#</a> 安装 zsh</h2>
<h3 id="编辑配置文件"><a class="anchor" href="#编辑配置文件">#</a> 编辑配置文件:</h3>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">vim</span> ~/.zshrc</pre></td></tr></table></figure><p>目前的:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token keyword">if</span> <span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token parameter variable">-r</span> <span class="token string">"<span class="token variable">$&#123;XDG_CACHE_HOME<span class="token operator">:-</span>$HOME<span class="token operator">/</span>.cache&#125;</span>/p12k-instant-prompt-<span class="token variable">$&#123;(<span class="token operator">%</span>)<span class="token operator">:-</span><span class="token operator">%</span>n&#125;</span>.zsh"</span> <span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span></pre></td></tr><tr><td data-num="2"></td><td><pre> <span class="token builtin class-name">source</span> <span class="token string">"<span class="token variable">$&#123;XDG_CACHE_HOME<span class="token operator">:-</span>$HOME<span class="token operator">/</span>.cache&#125;</span>/p11k-instant-prompt-<span class="token variable">$&#123;(<span class="token operator">%</span>)<span class="token operator">:-</span><span class="token operator">%</span>n&#125;</span>.zsh"</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token keyword">fi</span></pre></td></tr><tr><td data-num="4"></td><td><pre></pre></td></tr><tr><td data-num="5"></td><td><pre></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token assign-left variable">ZSH</span><span class="token operator">=</span>/usr/share/oh-my-zsh/</pre></td></tr><tr><td data-num="7"></td><td><pre></pre></td></tr><tr><td data-num="8"></td><td><pre><span class="token assign-left variable">ZSH_THEME</span><span class="token operator">=</span><span class="token string">"powerlevel10k/powerlevel10k"</span></pre></td></tr><tr><td data-num="9"></td><td><pre></pre></td></tr><tr><td data-num="10"></td><td><pre><span class="token assign-left variable">plugins</span><span class="token operator">=</span><span class="token punctuation">(</span></pre></td></tr><tr><td data-num="11"></td><td><pre> <span class="token function">sudo</span></pre></td></tr><tr><td data-num="12"></td><td><pre> <span class="token function">git</span></pre></td></tr><tr><td data-num="13"></td><td><pre> autojump</pre></td></tr><tr><td data-num="14"></td><td><pre> zsh-syntax-highlighting</pre></td></tr><tr><td data-num="15"></td><td><pre> zsh-autosuggestions</pre></td></tr><tr><td data-num="16"></td><td><pre><span class="token punctuation">)</span></pre></td></tr><tr><td data-num="17"></td><td><pre></pre></td></tr><tr><td data-num="18"></td><td><pre><span class="token assign-left variable">ZSH_CACHE_DIR</span><span class="token operator">=</span><span class="token environment constant">$HOME</span>/.cache/oh-my-zsh</pre></td></tr><tr><td data-num="19"></td><td><pre><span class="token keyword">if</span> <span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token operator">!</span> <span class="token parameter variable">-d</span> <span class="token variable">$ZSH_CACHE_DIR</span> <span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span></pre></td></tr><tr><td data-num="20"></td><td><pre> <span class="token function">mkdir</span> <span class="token variable">$ZSH_CACHE_DIR</span></pre></td></tr><tr><td data-num="21"></td><td><pre><span class="token keyword">fi</span></pre></td></tr><tr><td data-num="22"></td><td><pre></pre></td></tr><tr><td data-num="23"></td><td><pre></pre></td></tr><tr><td data-num="24"></td><td><pre><span class="token builtin class-name">source</span> <span class="token variable">$ZSH</span>/oh-my-zsh.sh</pre></td></tr><tr><td data-num="25"></td><td><pre></pre></td></tr><tr><td data-num="26"></td><td><pre><span class="token comment"># To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.</span></pre></td></tr><tr><td data-num="27"></td><td><pre><span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token operator">!</span> <span class="token parameter variable">-f</span> ~/.p10k.zsh <span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token builtin class-name">source</span> ~/.p10k.zsh</pre></td></tr><tr><td data-num="28"></td><td><pre><span class="token comment"># other name</span></pre></td></tr><tr><td data-num="29"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">sp</span><span class="token operator">=</span><span class="token string">'sudo pacman'</span> </pre></td></tr><tr><td data-num="30"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">syyu</span><span class="token operator">=</span><span class="token string">'yay -Syyu'</span> <span class="token comment"># 强制升级系统和软件包</span></pre></td></tr><tr><td data-num="31"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">syu</span><span class="token operator">=</span><span class="token string">'yay -Syu'</span> <span class="token comment"># 升级系统和软件包</span></pre></td></tr><tr><td data-num="32"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">c</span><span class="token operator">=</span><span class="token string">'clear'</span> <span class="token comment"># 清屏</span></pre></td></tr><tr><td data-num="33"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">e</span><span class="token operator">=</span><span class="token string">'exit'</span> <span class="token comment"># 退出终端</span></pre></td></tr><tr><td data-num="34"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">qq</span><span class="token operator">=</span><span class="token string">'rm -rf ~/.config/QQ/ &amp;&amp; linuxqq &amp;'</span> <span class="token comment"># 启动 QQ 时删除文件</span></pre></td></tr><tr><td data-num="35"></td><td><pre></pre></td></tr><tr><td data-num="36"></td><td><pre><span class="token comment"># git 快捷键 cd+add+commit+push+cd</span></pre></td></tr><tr><td data-num="37"></td><td><pre></pre></td></tr><tr><td data-num="38"></td><td><pre><span class="token comment"># 将本地 Note 仓库提交到 gihub</span></pre></td></tr><tr><td data-num="39"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">gpn</span><span class="token operator">=</span><span class="token string">'cd /home/origin/Code/repository/Note &amp;&amp; git add . &amp;&amp; git commit -m \"update\" &amp;&amp; git push &amp;&amp; cd -'</span></pre></td></tr><tr><td data-num="40"></td><td><pre></pre></td></tr><tr><td data-num="41"></td><td><pre><span class="token comment"># 将本地 Code_c 仓库提交到 gihub</span></pre></td></tr><tr><td data-num="42"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">gpc</span><span class="token operator">=</span><span class="token string">'cd /home/origin/Code/repository/Code_c &amp;&amp; git add . &amp;&amp; git commit -m \"update\" &amp;&amp; git push &amp;&amp; cd -'</span></pre></td></tr><tr><td data-num="43"></td><td><pre></pre></td></tr><tr><td data-num="44"></td><td><pre><span class="token comment"># 将本地 Code_cc 仓库提交到 gihub</span></pre></td></tr><tr><td data-num="45"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">gpcc</span><span class="token operator">=</span><span class="token string">'cd /home/origin/Code/repository/Code_cc &amp;&amp; git add . &amp;&amp; git commit -m \"update\" &amp;&amp; git push &amp;&amp; cd -'</span></pre></td></tr><tr><td data-num="46"></td><td><pre></pre></td></tr><tr><td data-num="47"></td><td><pre><span class="token comment"># 将本地 Python 仓库提交到 gihub</span></pre></td></tr><tr><td data-num="48"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">gppy</span><span class="token operator">=</span><span class="token string">'cd /home/origin/Code/repository/Code_py &amp;&amp; git add . &amp;&amp; git commit -m \"update\" &amp;&amp; git push &amp;&amp; cd -'</span></pre></td></tr><tr><td data-num="49"></td><td><pre></pre></td></tr><tr><td data-num="50"></td><td><pre><span class="token comment"># 将本地 my-xv6-labs-2022 仓库提交到 gihub</span></pre></td></tr><tr><td data-num="51"></td><td><pre><span class="token builtin class-name">alias</span> <span class="token assign-left variable">gplab</span><span class="token operator">=</span><span class="token string">'cd /home/origin/Code/repository/my-xv6-labs-2022 &amp;&amp; git add . &amp;&amp; git commit -m \"update\" &amp;&amp; git push &amp;&amp;cd -'</span></pre></td></tr><tr><td data-num="52"></td><td><pre></pre></td></tr><tr><td data-num="53"></td><td><pre><span class="token builtin class-name">export</span> <span class="token assign-left variable">GOPATH</span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$HOME</span>/go"</span></pre></td></tr><tr><td data-num="54"></td><td><pre><span class="token builtin class-name">export</span> <span class="token assign-left variable"><span class="token environment constant">PATH</span></span><span class="token operator">=</span><span class="token string">"<span class="token environment constant">$PATH</span>:/usr/lib/go/bin:<span class="token variable">$GOPATH</span>/bin"</span></pre></td></tr><tr><td data-num="55"></td><td><pre><span class="token builtin class-name">export</span> <span class="token assign-left variable"><span class="token environment constant">PATH</span></span><span class="token operator">=</span>/usr/sbin:<span class="token environment constant">$PATH</span></pre></td></tr></table></figure><p>## 为一个文件或目录创建一个符号链接:</p>
<p>在 <code>/usr/local/local</code> 中存有已经建立的符号链接,在 <code>/usr/share</code> 中有通过自行下载的装包安装的软件,如通过官网安装包安装的 code。</p>
<p>输入 <code>ln -s [文件/目录路径] [建立后的软链接名称]</code> ,即可建立链接。如: <code>ln -s /usr/share/code/code code</code></p>
<h2 id="更改默认jva环境"><a class="anchor" href="#更改默认jva环境">#</a> 更改默认 Jva 环境</h2>
<h3 id="安装java环境java-20-jdk"><a class="anchor" href="#安装java环境java-20-jdk">#</a> 安装 Java 环境(Java-20-jdk)</h3>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Sy</span> <span class="token parameter variable">--needed</span> <span class="token parameter variable">--noconfirm</span> jdk</pre></td></tr></table></figure><p>输入</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>archlinux-java status</pre></td></tr></table></figure><p>若出现类似下面,即为安装成功</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>Available Java environments:</pre></td></tr><tr><td data-num="2"></td><td><pre> java-21-jdk</pre></td></tr><tr><td data-num="3"></td><td><pre> java-21-openjdk</pre></td></tr><tr><td data-num="4"></td><td><pre> java-8-openjdk <span class="token punctuation">(</span>default<span class="token punctuation">)</span></pre></td></tr></table></figure><p>若 java-21-openjdk 为 default 则已成功将 java21 设置为默认环境,若不是,则输入</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> archlinux-java <span class="token builtin class-name">set</span> java-20-openjdk<span class="token punctuation">[</span>你想要设为默认的java环境名<span class="token punctuation">]</span></pre></td></tr></table></figure><p>后输入 <code>archlinux-java status</code> 查看, java-21-openjdk 已是 default</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>Available Java environments:</pre></td></tr><tr><td data-num="2"></td><td><pre> java-21-jdk</pre></td></tr><tr><td data-num="3"></td><td><pre> java-21-openjdk <span class="token punctuation">(</span>default<span class="token punctuation">)</span></pre></td></tr><tr><td data-num="4"></td><td><pre> java-8-openjdk</pre></td></tr></table></figure><h2 id="archlinux内存管理"><a class="anchor" href="#archlinux内存管理">#</a> ArchLinux 内存管理</h2>
<ol>
<li>
<p>清除 Arch Linux 上的包缓存和 AUR 软件包</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>pacman <span class="token parameter variable">-Scc</span></pre></td></tr><tr><td data-num="2"></td><td><pre>yay <span class="token parameter variable">-Scc</span></pre></td></tr></table></figure><p>Arch Linux 在 /var/cache/pacman/pkg/ 目录中存储下载的每个软件包,包括升级。如果更新破坏了软件包,便于回滚到以前的版本。 /home/origin/.cache/yay 存有 AUR 的软件包。下面的名令将从缓存 /var/cache/pacman/pkg/ 中删除当前未安装的所有包。在命令中添加另一个 **-c**(最后有两个 c)标志将删除所有缓存的包。</p>
</li>
<li>
<p>删除孤立的软件包</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Qtdq</span> 查看删除孤立的软件包</pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-Rns</span> <span class="token variable"><span class="token variable">$(</span>pacman <span class="token parameter variable">-Qtdq</span><span class="token variable">)</span></span></pre></td></tr></table></figure></li>
<li>
<p>清理日志,设置了固定大小为 50M,多的日志会被删掉。</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>journalctl --vacuum-size<span class="token operator">=</span>50M</pre></td></tr></table></figure></li>
</ol>
<h2 id="python-使用-pip-遇到问题"><a class="anchor" href="#python-使用-pip-遇到问题">#</a> python 使用 pip 遇到问题</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre>pip <span class="token function">install</span> scikit-learn</pre></td></tr><tr><td data-num="2"></td><td><pre>error: externally-managed-environment</pre></td></tr><tr><td data-num="3"></td><td><pre></pre></td></tr><tr><td data-num="4"></td><td><pre>× This environment is externally managed</pre></td></tr><tr><td data-num="5"></td><td><pre>╰─<span class="token operator">></span> To <span class="token function">install</span> Python packages system-wide, try <span class="token string">'pacman -S</pre></td></tr><tr><td data-num="6"></td><td><pre> python-xyz'</span>, where xyz is the package you are trying to</pre></td></tr><tr><td data-num="7"></td><td><pre> install.</pre></td></tr><tr><td data-num="8"></td><td><pre> </pre></td></tr><tr><td data-num="9"></td><td><pre> If you wish to <span class="token function">install</span> a non-Arch-packaged Python package,</pre></td></tr><tr><td data-num="10"></td><td><pre> create a virtual environment using <span class="token string">'python -m venv path/to/venv'</span><span class="token builtin class-name">.</span></pre></td></tr><tr><td data-num="11"></td><td><pre> Then use path/to/venv/bin/python and path/to/venv/bin/pip.</pre></td></tr><tr><td data-num="12"></td><td><pre> </pre></td></tr><tr><td data-num="13"></td><td><pre> If you wish to <span class="token function">install</span> a non-Arch packaged Python application,</pre></td></tr><tr><td data-num="14"></td><td><pre> it may be easiest to use <span class="token string">'pipx install xyz'</span>, <span class="token function">which</span> will manage a</pre></td></tr><tr><td data-num="15"></td><td><pre> virtual environment <span class="token keyword">for</span> you. Make sure you have python-pipx</pre></td></tr><tr><td data-num="16"></td><td><pre> installed via pacman.</pre></td></tr><tr><td data-num="17"></td><td><pre></pre></td></tr><tr><td data-num="18"></td><td><pre>note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.</pre></td></tr><tr><td data-num="19"></td><td><pre>hint: See PEP <span class="token number">668</span> <span class="token keyword">for</span> the detailed specification.</pre></td></tr></table></figure><p>解决:</p>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> <span class="token function">rm</span> /usr/lib/python3.11/EXTERNALLY-MANAGED</pre></td></tr></table></figure><h2 id="修改用户名及用户目录"><a class="anchor" href="#修改用户名及用户目录">#</a> 修改用户名及用户目录</h2>
<ol>
<li>切换终端,用 root 账户登录;</li>
<li>编辑 /etc/passwd 文件,将旧用户名替换为新用户名;</li>
<li>编辑 /etc/shadow 文件,将旧用户名替换为新用户名;</li>
<li>编辑 /etc/group 文件,将旧用户名替换为新用户名;</li>
<li>重命名 home 文件: mv /home/oldusername/home/newusername</li>
</ol>
<p>注:目录名的改变会导致一些固定路径的配置项发生错误,需要手动修改路径。</p>
<h2 id="linux-修改u盘名称"><a class="anchor" href="#linux-修改u盘名称">#</a> Linux 修改 U 盘名称</h2>
<figure class="highlight bash"><figcaption data-lang="bash"></figcaption><table><tr><td data-num="1"></td><td><pre><span class="token function">sudo</span> pacman <span class="token parameter variable">-S</span> <span class="token function">mtools</span> <span class="token comment"># 安装工具</span></pre></td></tr><tr><td data-num="2"></td><td><pre><span class="token function">sudo</span> <span class="token function">vim</span> /etc/mtools.conf <span class="token comment"># 然后修改配置文件</span></pre></td></tr><tr><td data-num="3"></td><td><pre><span class="token comment"># 在这个文件最后添加下面一行</span></pre></td></tr><tr><td data-num="4"></td><td><pre><span class="token assign-left variable">mtools_skip_check</span><span class="token operator">=</span><span class="token number">1</span></pre></td></tr><tr><td data-num="5"></td><td><pre><span class="token function">sudo</span> mlabel <span class="token parameter variable">-i</span> /dev/sdb1 ::DISK2 <span class="token comment"># sdb1 是 U 盘,SISK2 是修改后的名称(自动改大写)</span></pre></td></tr><tr><td data-num="6"></td><td><pre><span class="token function">sudo</span> <span class="token function">eject</span> /dev/sdb1 <span class="token comment"># 修改完成</span></pre></td></tr></table></figure></content>
<category term="ArchLinux" scheme="http://yuanmxc.site/categories/ArchLinux/" />
<updated>2024-03-26T11:49:10.133Z</updated>
</entry>
<entry>
<id>http://yuanmxc.site/C++/C++%20Primer%E7%AC%94%E8%AE%B0/</id>
<title>C++ Primer笔记</title>
<link rel="alternate" href="http://yuanmxc.site/C++/C++%20Primer%E7%AC%94%E8%AE%B0/"/>
<content type="html"><p>注意:本文并不是教你学 C++,这只是笔者学习 C<ins> 过程中记录的相关知识,适用于已经对 C</ins> 有所了解的读者进行复习和查询,读者至少对 C 和 C++ 有所了解。</p>
<h2 id="小记"><a class="anchor" href="#小记">#</a> 小记:</h2>
<ol>
<li>
<p>有符号和无符号一起用,有符号转无符号。</p>
</li>
<li>
<p>double(一般 16 有效位)一般和 float(一般 7 有效位)运算代价相同,用 double 即可。</p>
</li>
<li>
<p>char16_t 和 char32_t 为 Unicode 字符,包含所有自然语言字符。</p>
</li>
<li>
<p>泛化的转义序列: <code>\x</code> 后跟 1 或多个十六进制数字或者 <code>\</code> 后跟多个八进制数字: <code>\12</code> (换行符) <code> \x4d</code> (字符 M)</p>
</li>
<li>
<p>初始化不是赋值,定义变量时若未指定初始值,变量被<strong>默认初始化</strong>,“默认值” 由变量类型和定义位置决定。定义在任何函数体之外的内置类型变量会被默认初始化为 0,定义在函数体内部的内置类型变量不被初始化,它的值是未定义的。每个类各自决定初始化对象的方式。</p>
</li>
<li>
<p>声明使得名字为程序所知,定义负责创建于名字关联的实体。变量能且只能被定义一次,但是可以被多次声明。任何包含了显式初始化的声明即成为定义。多个文件使用同一变量,只能有一个定义,其他文件必须声明才能使用,决不能定义该变量。</p>
<pre><code class="language-c++">extern int i; // 声明i而非定义i
int j; // 声明并定义j
extern double pi = 3.1415926; // 定义,extern作用被抵消
</code></pre>
</li>
<li>
<p>引用只是一个已经存在的对象的另一个名字,它和它的初始值(一个对象)一直绑定在一起,必须被初始化。对引用的操作就是对于它绑定的对象的操作(可以视为替换)。引用本身不是对象,无法定义引用的引用和指针。</p>
<pre><code class="language-c++">int ival = 1024;
int &amp;refVal = ival;
refVal = 2;
</code></pre>
</li>
<li>
<p><code>::</code> 作用域运算符,使用 <code>::reuserd</code> 的方式可以访问被局部变量覆盖的全局变量,全局作用域本身没有名字,所以 <code>::</code> 左侧为空时会向全局作用域发起请求。</p>
</li>
<li>
<p>把 int 变量直接赋给指针是错误的操作,即使他的值为 0。</p>
</li>
<li>
<p>对指针的引用:</p>
</li>
</ol>
<pre><code class="language-c++">int i = 21;
int *p;
int *&amp;r = p;
r = &amp;i; // 令p指向i
*r = 0; // 将p指向的变量i的值改为0
</code></pre>
<ol start="11">
<li>
<ul>
<li>
<p>当以编译时初始化的方式定义一个 const 对象时,例如: <code>const int bufSize = 512;</code> ,编译器会将在编译过程中用到该变量的地方都替换成对应的值。</p>
</li>
<li>
<p>默认状态下,const 对象被设定为仅在文件内有效。当多个文件中出现同名 const 变量时,等同于在不同文件中分别定义了独立的变量</p>
</li>
<li>
<p>当希望 const 变量初始值不是常量表达式,但需要在文件间共享,即和其他对象一样,只在一个地方定义 const 变量,而在其他多个文件中声明并使用它,则不管是声明还是定义都添加 extern 关键字,这样只需要定义一次就可以了。</p>
<pre><code class="language-c++">// file_1.cc 定义并初始化了一个常量,该常量能被其他文件访问
extern const int bufSize = fcn();
// file_1.h 头文件
extern const int bufSize; // 与file_1.cc 中定义的bufSize是同一个
</code></pre>
</li>
</ul>
</li>
<li>
<p>对 const 对象的引用称之为对常量的引用(<strong>常量引用</strong>)。不能让一个非常量引用指向一个常量对象。</p>
</li>
<li>
<p>一般来说引用的类型应该与其所引用的对象的类型一致,但有下面两个例外:</p>
<ul>
<li>
<p>对 const 的引用可能引用一个并非 const 的对象。</p>
<pre><code class="language-c++">int i = 42;
int &amp;r1 = i;
const int &amp;r2 = i; // r2绑定对象i但是不允许通过r2修改i的值。
</code></pre>
</li>
<li>
<p>初始化常量引用时允许使用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可,尤其,允许为一个常量引用绑定非常量的对象、字面值,甚至是一个表达式:</p>
<pre><code class="language-c++">double i = 3.14;
const int &amp;r1 = i; // 正确,double可以转换成int,常量引用可以绑定非常量对象
const int &amp;r2 = 42; // 正确:r2是一个常量引用,可以绑定字面值
const int &amp;r3 = r1 * 2; // 正确:r3是一个常量引用,可以绑定表达式
int &amp;r4 = r1 *2 // 错误:r4是一个普通的非常量引用
</code></pre>
<p>以上面第 1、2 行代码为例,当一个常量引用被绑定到另一种类型上时,编译器把 i 转化一个整形常量 3,这个 3 是一个临时量对象,是编译器需要的一个用来暂存表达式求值结果时临时创建的一个未命名的对象。</p>
</li>
</ul>
</li>
<li>
<p>一般来说指针的类型应该与其所指对象的类型一致,但有下面两个例外:</p>
<ul>
<li>允许一个指向常量的指针指向另一个非常量的对象。</li>
<li>常量指针可以指向非常量对象。</li>
</ul>
</li>
<li>
<p><strong>顶层 const</strong> 表示指针本身是一个常量,<strong>底层 const</strong> 表示指针所值的对象是一个常量。当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层 const 资格,或者两个对象的数据类型必须能够转换,一般来说,非常量可以转换成常量,反之则不行。</p>
</li>
<li>
<p>将变量声明为 constexptr 类型,让编译器来验证变量的值是否是一个常量表达式(值不会改变且在编译过程就能得到计算结果的表达式)。</p>
<pre><code class="language-c++">constexpr =int mf = 20;
</code></pre>
</li>
<li>
<p>定义类型别名:</p>
<pre><code class="language-c++">typedef double wages; // wages是double的同义词
typedef wasges base, *p; // base是double的同义词,p是double*的同义词
using SI = Sales_item; // SI是Sales_item的同义词
</code></pre>
</li>
<li>
<p>简单的把类型别名替换成它原本样子可能是错误的,后两句如果进行简单的文本替换,基本数据类型变为 const char .</p>
<pre><code class="language-c++">const char *cstr = 0; // 声明的是一个指向 const char 的指针
typedef char *pstring; // pstring的类型是指向char的指针
const pstring cstr = 0; // cstr是指向char的常量指针
const pstring *ps; // ps是一个指针,他指向的对象是一个指向char的常量指针
</code></pre>
</li>
<li>
<p>auto 一般会忽略掉<strong>顶层 const</strong> ,同时<strong>底层 const</strong> 会被保留。想保留,需要用 const atuo 。设置一个类型为 auto 的引用时,初始值中的顶层常量属性仍然被保留。</p>
</li>
<li>
<p>decltype ( ) 返回()中表达式的类型。如果 decltype 使用的表达式是一个变量,则 decltype 返回该变量的类型(包括顶层 const 和引用在内)。如果表达式的内容是解引用操作,则 decltype 将得到引用类型。decltype 使用的表达式是变量,该变量是否有括号会影响结果,如果无括号,得到的类型是该变量的类型,如果有括号,得到的是该变量对应的引用类型。</p>
<pre><code class="language-c++">decltype (f()) sum = x; // sum的类型就是函数f的返回类型,编译器并不实际调用f()
// decltype的结果可以是引用类型
int i = 42, *p = &amp;i, &amp;r = i;
decltype(r + 0) b; // 正确:加法的结果是int,因此b是一个(未初始化的)int
decltype(*p) c; // 错误:*p的类型是int,但他是解引用操作,所以c的类型是int&amp;,必须初始化
decltype((i)) d; // 错误:使用(i)得到的是 int&amp; 类型,必须初始化
</code></pre>
</li>
<li>
<p>头文件保护符 <code>#ifndef</code> 、 <code>#ifdef</code> 、 <code>#endif</code> 应该包含在头文件中,即使头文件(目前还)没有被包含在任何其他头文件中。头文件不应该使用 using 声明。</p>
</li>
<li>
<p>string 字符串使用字符串字面值初始化时,不包含字符串字面值最后隐藏的空字符,字符串字面值实际上包含写出来的字符和隐藏的空字符。</p>
</li>
<li>
<p>cin 在读取 string 时,string 对象会自动忽略开头的空白(空格符、换行符、制表符等),并从第一个真正的字符开始读起,直到遇见下一次处空白为止。</p>
</li>
<li>
<p><code>getline(cin, line)</code> 读取一整行,参数是一个输入流和一个 string 对象,函数从输入流中读入内容,直到遇到换行符为止(换行符也被读进来了),然后把所读的对象存入到 string 对象中(但是不存读入的换行符)。如果一开始就输入换行符,那么得到空 string。触发 getline 函数返回的换行符实际上被丢掉了。</p>
</li>
<li>
<p>sting 操作中的 size () 等函数,返回的数字类型配套的, <code>size()</code> 返回 <code>string:: size_type</code> 类型,一个无符号整型,使用 <code>auto</code> 或者 <code>decltype()</code> 推断变量类型来存比较好。注意无符号整型和有符号整型混用的问题。</p>
</li>
<li>
<p>string 比较规则:返回两个 string 对象第一个不同字符的比较结果,若全相同,则长的大。</p>
</li>
<li>
<p>当把 string 对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是 string,字符串字面值不是 string 对象。</p>
</li>
<li>
<p>string 的下标运算符接收的参数是 string::size_type 类型的值,返回值是该位置上字符的引用。在范围 for 语句中也需要使用引用来修改 string 中的字符,使用 char 的话没有改变原 string 对象。</p>
</li>
<li>
<p><strong>string</strong>:</p>
<pre><code class="language-c++">// 初始化
string s1; // 默认初始化,空字符串
string s2 = &quot;&quot;; // 拷贝初始化,空字符串
string s3 = &quot;hello&quot;; // 拷贝初始化
string s4(&quot;world&quot;); // 拷贝初始化,使用构造函数定义并初始化字符串
string s5(10,'c'); // 直接初始化,是十个c的字符串
string s6 = string(10,'c') // 拷贝初始化,创建了一个临时对象然后拷贝给s6
// 成员函数
s[n] // 返回n位置上的字符的引用
s.empty() // s是否为空,空为真,不空为假
s.length() // 或者 s.size(),返回s中字符个数
s.at(n); // 返回下标为n的字符
s.find(&quot;ld&quot;); // 返回 &quot;ld&quot; 在字符串中的位置n
s.replace(6, 5, &quot;there&quot;); // 把 &quot;world&quot; 替换成 &quot;there&quot;
s.substr(0, 5); // 返回i字符串的前5个字符组成的字符串
s.substr(6); // 返回从字符串的第7个字符到末尾的字符组成的字符串
s.insert(6, &quot;there&quot;); // 在下标为6的位置插入there“,后面字符顺延
s.insert(6, 1, '-'); // 在第6个位置插入 '-',后面字符顺延
</code></pre>
</li>
<li>
<p>使用花括号初始化 vector 对象时,会优先使用列表初始化,提供的值必须与元素类型相同,如果不同,无法执行列表初始化,编译器会尝试使用默认初始化 vector 对象。</p>
</li>
<li>
<p>一般创建一个空的 vector ,再向里面添加元素更好,直接初始化可能性能更差,同时,如果改变了 vector 容量,不应使用范围 for 循环,范围 for 语句内不应该改变其所遍历序列的大小。不能使用下标形式为 vector 添加元素,只能对已存在的元素执行下标操作。</p>
</li>
<li>
<p>** 类模板 vector **:</p>
<p>vector 定义在头文件中,需要包含,并位于 std 命名空间中。</p>
<pre><code class="language-c++">vector&lt;double&gt; v; // 创建空容器
vector&lt;string&gt; v1&#123;10&#125;; // 10不是string,使用默认初始化,初始化有10个string的vectoer
vector&lt;double&gt; v(20, 1.0); // 直接初始化有20个double的vectoe,初始值均为1.0,没有第二个参数初始值默认均为0,使用花括号也可
vector&lt;int&gt; values2&#123;1,2,3,4,2,1&#125;; // 指定元素个数和初始值
vector&lt;int&gt; values3(values2); // 创建和alces相同的容器
vector&lt;int&gt; values4(begin(value2,begin(v。alue2)+3)) // 使用指针或者迭代器来指定初始值范
</code></pre>
<p>vector 容器包含的成员函数:</p>
<pre><code class="language-c++">begin() // 返回指向容器中第一个元素的迭代器。
end() // 返回指向容器最后一个元素所在位置后一个位置的迭代器。
front() // 返回第一个元素的引用。
back() // 返回最后一个元素的引用。
data() // 返回指向容器中第一个元素的指针。
assign() // 用新元素替换原有内容。
push_back() // 在序列的尾部添加一个元素。
pop_back() // 移出序列尾部的元素。
insert() // 在指定的位置插入一个或多个元素。
erase() // 移出一个元素或一段元素。
clear() // 移出所有的元素,容器大小变为 0。
rbegin() // 返回指向最后一个元素的迭代器。
rend() // 返回指向第一个元素所在位置前一个位置的迭代器。
cbegin() // 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
cend() // 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin() // 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend() // 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size() // 返回实际元素个数 类型是vector&lt;T&gt;::size_type,T为vector存储的元素类型。
max_size()// 返回元素个数的最大值。这通常是一个很大的值,一般是 2^32-1,所以我们很少会用到这个函数。
resize() // 改变实际元素的个数。
capacity()// 返回当前容量。
empty() // 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
reserve() // 增加容器的容量。
shrink _to_fit() // 将内存减少到等于当前元素实际所使用的大小。
operator[ ] // 重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。
at() // 使用经过边界检查的索引访问元素。
swap() // 交换两个容器的所有元素。
emplace() // 在指定的位置直接生成一个元素。
emplace_back() // 在序列尾部生成一个元素。
</code></pre>
</li>
<li>
<p>如果容器为空,begin 和 end 都返回尾后迭代器。</p>
</li>
<li>
<p>标准容器迭代器的部分运算符:</p>
<pre><code class="language-c++">*it // 返回迭代器it所指元素的引用
(*it).empty() // it指示一个strng类型并判断string是否为空,必须加(),否则先进行点运算
it-&gt;empty() // 解引用it并获取该元素的名为mem的成员,等价于(*it).empty()
++it // 令it指示容器中的下一个元素
--it // 令it指示容器中的上一个元素
it1 == it2 // 判断两个选代器是否相等,如果两个选代器指示的是同一个元素或者它们是同一个容器的尾后选代器,则相等;反之,不相等
+、-、+=、-=、&lt;、&gt;、&lt;=、&gt;=
</code></pre>
</li>
<li>
<p>某些对 vector 的操作(任何可能改变 vertor 对象容量的操作)会使迭代器失效,比如 push_back,不能在范围 for 循环中向 vector 对象添加元素。</p>
</li>
<li>
<p>遍历一个 vector :</p>
<pre><code class="language-c++">vector&lt;int&gt; vec = &#123;1,2,3,4&#125;;
// 范围for循环
for(const auto&amp; element : vec)&#123;
cout &lt;&lt; element &lt;&lt; endl;
&#125;
// 迭代器遍历
for(vector&lt;int&gt;::iterator it = vec.begin(); it != vec.end(); ++it)&#123;
cout &lt;&lt; *it &lt;&lt; end;
&#125;
// 索引遍历
for(size_t i = 0; i &lt; vec.size(); ++i)&#123;
cout &lt;&lt; vec[i] &lt;&lt; endl;
&#125;
</code></pre>
</li>
<li>
<p>使用迭代器的二分搜索:</p>
<pre><code class="language-c++">// text必须是有序的
// beg和end表示我们搜索的范围
auto beg = text.begin(), end=text.end();
auto mid = text.begin() + (end-beg)/2; // 初始状态下的中间点
// 当还有元素尚未检查并且我们还没有找到sought时执行循环
while(mid != end &amp;&amp; *mid != sought)
if (sought &lt; *mid) // 如果要找的元素在前半部分
end = mid; // 新end为旧mid,beg不变
else // 否则,我们要找的元素在后半部分
beg = mid + 1 // 新beg为旧mid+1,end不变
mid = beg + (end-beg)/2; // 同样方法计算新的中间点
</code></pre>
</li>
<li>
<p>数组的维度(元素个数)必须是常量表达式。默认情况下数据元素北默认初始化。字符数组使用字符串字面值初始化时,后面隐藏的 '\0' 会被包含进去,空间不够时报错。数组不允许拷贝和赋值。</p>
</li>
<li>
<p>数组本身是对象,存放对象,不存在引用的数组,但存在数组的引用。</p>
<pre><code class="language-c++">unsigned cnt = 42; //不是常量表达式
constexpr unsigned sz = 42;//常量表达式
int *parr[sz]; //含有42个整型指针的数组
string bad[cnt];; //错误:cnt不是常量表达式
string strs[get_size()]; //当get_size是constexpr时正确;否则错误
</code></pre>
</li>
<li>
<p>当数组作为一个 auto 变量的初始值时,推断得到的类型是指针而非数组;使用 decltype 关键字时返回的类型是数组。</p>
</li>
<li>
<p>标准库函数 begin () 和 end () 获取数组的首元素指针和尾元素下一指针。两个指针相减的结果类型是 ptrdiff_t 的标准库类型,是带符号类型。如果两个指针分别指向不相关的对象,不能比较他们,未定义行为。</p>
</li>
<li>
<p>使用数组下标等同于使用指针,同时内置的下标运算(数组下标)可以处理负值,但标准库类型 string 和 vector 的下标运算必须是无符号类型。</p>
</li>
<li>
<p>尽量少使用 C 风格字符串,内存管理麻烦,多用 string,string 的成员函数 c_str () 可以把 string 转化成 char*。</p>
</li>
<li>
<p>数组无法拷贝和赋值,不能用 vector 初始化数组,但可以用数组初始化 vector ,只需之名拷贝区域的首元素地址和尾后地址:</p>
<pre><code class="language-c++">int int_arr[] = &#123;0, 1, 2, 3, 4, 5&#125;;
// ivec有6个元素,分别是intarr中对应元素的副本
vector&lt;int&gt; ivec(begin(int_arr),end(int_arr));
</code></pre>
</li>
<li>
<p>当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。</p>
</li>
</ol>
<h3 id="运算符"><a class="anchor" href="#运算符">#</a> 运算符</h3>
<ol start="45">
<li>
<p>有 4 种运算符明确规定了运算对象的求值顺序。逻辑与(&amp;&amp;)运算符和逻辑或(||)运算符规定先求左侧运算对象的值,只有当左侧运算对象的值为真 / 假时才继续求右侧运算对象的值。条件( ?: )运算符和逗号( , )运算符。其他运算符,如 + 、&gt;&gt; 等未规定左右运算对象的求值顺序,先求左右表达式中的哪一个都有可能。如果表达式影响同一对象,求值先后顺序对结果有影响,那么它是一个错误的表达式,将产生未定义行为。</p>
</li>
<li>
<p>布尔值不应该参与运算,大多数运算符会把布尔值提升为 int 类型,true 为 1,求负后为 -1 ,再转回布尔值时仍为 1 ,还是 true。</p>
</li>
<li>
<p>求商向 0 取整(直接切除小数部分)。取余时,除了 -m 导致溢出的情况,m % (-n) 等于 m % n,( -m ) % n 等于 -( m % n ),即左右都为负,结果是两个正数取余后结果取反,一正一负,结果等于两个正数取余。</p>
</li>
<li>
<p>位运算符的运算对象是 “小整数”,它的值会被自动提升成较大的整数类型”,如何处理负数对象的 “符号位” 依赖于机器,而且此时的左移操作可能会改变符号位的值,因此是一种未定义的行为。左移在右侧插入 0。右移时,无符号类型左侧插入 0,带符号类型插入符号位的副本或者值为 0 的二进制位,如何选择视具体情况而定。</p>
</li>
<li>
<p>sizeof 运算符对解引用指针进行运算不会验证指针是否有效,对指针进行运算返回指针本身所占空间大小,对数组返回整个数组所占空间大小。对 sring 或者 vector 运算返回该类型固定部分的大小。sizeof 返回值是一个常量表达式。</p>
</li>
<li>
<p>逗号( , )运算符按照从左向右的顺序求值,运算结果是右侧表达式的值。</p>
</li>
<li>
<p>无符号和有符号数一起运算时,无符号类型所占位数大于等于有符号类型,则有符号类型转为无符号类型;如果无符号类型所占位数小于有符号类型,比如 long 和 unsigned int ( long 大于 int 时),则 unsigned int 转为 long</p>
</li>
<li>
<p>命名的强制类型转换具有如下形式: <code>cast-name(expression)</code> ,static_cast 是一种只要类型不包含底层 const 都可用。const_cast 只能改变运算对象的底层 const, 不能进行类型转换。</p>
</li>
<li>
<p>switch case 语句中,后面的 case 标签可以使用前面的 case 标签定义过的变量,但是该变量的初始化无效(如果前 case 标签被跳过的话),包括类似 string 的默认初始化。即:不允许跨过变量的初始化语句直接跳转到该变量作用域内的另一个位置。</p>
</li>
<li></li>
</ol>
<h3 id="常用函数"><a class="anchor" href="#常用函数">#</a> 常用函数</h3>
<pre><code class="language-c++">// cctype 头文件中的函数
isalnur(c) // 当c是字母或数字时为真
isalpha(c) // 当c是字母时为真
iscntrl(n) // 当c是控制字符时为真
isdigit(c) // 当c是数字时为真
isgraph(c) // 当c不是空格但可打印时为真
islower(c) // 当c是小写字母时为真
isprint(c) // 当c是可打印字符时为真(即c是空格或c具有可视形式)
ispunct(c) // 当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)
isspace(c) // 当c是空白时为真(即c是空格、横向制表符、纵向制表符、回车符、换行符、进纸符中的一种)
isupper(c) // 当c是大写字母时为真
isxdigit(c) // 当c是十六进制数字时为其
tolower(c) // 如果c是大写字母,输出对应的小写字母:否则原样输出c
toupper(c) // 如果c是小写字母,输出对应的大写字母:否则原样输出c
</code></pre>
<h3 id="头文件"><a class="anchor" href="#头文件">#</a> 头文件:</h3>
<pre><code class="language-C++">#include &lt;initializer_list&gt;
#include &lt;iostream&gt;
#include &lt;istream&gt;
#include &lt;ostream&gt;
#include &lt;stdexcept&gt;
#include &lt;string&gt;
#include &lt;cstdarg&gt; // 使用va_list可变参数列表
#include &lt;system_error&gt;
#include &lt;vector&gt; // 使用vector容器
#include &lt;string&gt;
#include &lt;cstdlib&gt; // 预处理变量NULL
#include &lt;cctype&gt; // 使用nullptr,isalnum(),isalpha()等
#include &lt;cstddef&gt; // 使用size_t,ptrdiff_t
#include &lt;iterator&gt; // 使用begin(),end()
#include &lt;stdexcept&gt; // 异常类,如runtime_error,p176
</code></pre>
<h3 id="全局区"><a class="anchor" href="#全局区">#</a> 全局区</h3>
<pre><code class="language-c++">#include &lt;cassert&gt; // assert,预处理宏
using std::cin; // using声明,当我们使用cin时,意味着使用的std::cin
using namespace std;// 头文件内容会拷贝到所有引用他的文件里,一般不应包含using声明(易造成名字冲突)
// 如果定义了预处理变量MIN,就继续到#endif,#indef和#indef叫预处理百年
#ifdef MIN
#define MKSTR(x) #x // &quot;x&quot;
#endif
// 如果没有定义预处理变量MIN,就继续到#endif,一般头文件的预处理变量定义都需要这样写
#ifndef MIN
#define MIN(a, b) (a &lt; b ? a : b)
#define concat(a, B) a##b // xy
#define NDEBUG // 定了他 assert什么都不做,没定义则指执行运行时检查
#endif
extern const int i = 123; // a文件里定义并初始化i,加extern使其能被其他文件使用
</code></pre>
<h3 id="数据结构"><a class="anchor" href="#数据结构">#</a> 数据结构</h3>
<ol>
<li>
<p>stack 容器</p>
<p>头文件,c 在 std 命名空间。stack 容器适配器的模板有两个参数。第一个参数是存储对象的类型,第二个参数是底层容器的类型。stack 的底层容器默认是 deque 容器,因此模板类型其实是 stack。通过指定第二个模板类型参数,可以使用任意类型的底层容器,只要它们支持 back ()、push_back ()、pop_back ()、empty ()、size () 这些操作。下面展示了如何定义一个使用 list 的堆栈:</p>
<pre><code class="language-c++">stack&lt;string&gt; words1; // 省略第一个参数,用默认的底层容器deque&lt;T&gt;实现
stack&lt;string, list&lt;string&gt;&gt; words2 // 底层容器使用list&lt;T&gt;
</code></pre>
<p>创建堆栈时,不能用对象来初始化,但是可以用另一个容器来初始化,只要堆栈的底层容器类型和这个容器的类型相同,且必须使用圆括号。例如:</p>
<pre><code class="language-c++">list&lt;double&gt; values &#123;1.414, 3.14159265, 2.71828&#125;;
stack&lt;double, list&lt;double&gt;&gt; my_stack (values);
</code></pre>
<p>第二条语句生成了一个包含 value 元素副本的 my_stack。这里不能在 stack 构造函数中使用初始化列表,必须使用圆括号。如果没有在第二个 stack 模板类型参数中将底层容器指定为 list,那么底层容器可能是 deque,这样就不能用 list 的内容来初始化 stack;只能接受 deque。</p>
<p>stack 模板定义了拷贝构造函数,因而可以复制现有的 stack 容器:</p>
</li>
</ol>
<pre><code class="language-c++">stack copy_stack &#123;my_stack&#125;
</code></pre>
<p>堆栈操作:(T 为栈中元素类型)</p>
<ul>
<li>
<p>push (const T&amp; obj) 可以将对象副本压入栈顶。这是通过调用底层容器的 push_back () 函数完成的。</p>
<ul>
<li>pop () 弹出栈顶元素但没有返回它。</li>
</ul>
</li>
<li>
<p>top () 返回一个栈顶元素的引用但没有弹出,类型为 T&amp;。如果栈为空,返回值未定义。</p>
<ul>
<li>
<p>size () 返回栈中元素的个数。</p>
</li>
<li>
<p>empty () 在栈中没有元素的情况下返回 true。</p>
</li>
<li>
<p>emplace () 用传入的参数调用构造函数,在栈顶生成对象。</p>
</li>
<li>
<p>swap (stack &amp; other_stack) 将当前栈中的元素和参数中的元素交换。参数所包含元素的类型必须和当前栈的相同。对于 stack 对象有一个特例化的全局函数 swap () 可以使用。</p>
</li>
</ul>
</li>
</ul>
<ol start="2">
<li>
<p>类模板</p>
<p>vector 定义在头文件中,需要包含,并位于 std 命名空间中。</p>
<pre><code class="language-c++">vector&lt;double&gt; values; // 创建空容器
vector&lt;double&gt; values1(20, 1.0); // 开始就有20个int,初始值均为1.0,没有第二个参数初始值默认均为0
vector&lt;int&gt; values2&#123;1,2,3,4,2,1&#125;; // 指定元素个数和初始值
vector&lt;int&gt; values3(values2); // 创建和alces相同的容器
vector&lt;int&gt; values4(begin(value2,begin(v。alue2)+3)) // 使用指针或者迭代器来指定初始值范围
</code></pre>
<p>vector 容器包含的成员函数:</p>
<pre><code class="language-c++">begin() // 返回指向容器中第一个元素的迭代器。
end() // 返回指向容器最后一个元素所在位置后一个位置的迭代器。
front() // 返回第一个元素的引用。
back() // 返回最后一个元素的引用。
data() // 返回指向容器中第一个元素的指针。
assign() // 用新元素替换原有内容。
push_back() // 在序列的尾部添加一个元素。
pop_back() // 移出序列尾部的元素。
insert() // 在指定的位置插入一个或多个元素。
erase() // 移出一个元素或一段元素。
clear() // 移出所有的元素,容器大小变为 0。
rbegin() // 返回指向最后一个元素的迭代器。
rend() // 返回指向第一个元素所在位置前一个位置的迭代器。
cbegin() // 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
cend() // 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin() // 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend() // 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size() // 返回实际元素个数。
max_size()// 返回元素个数的最大值。这通常是一个很大的值,一般是 2^32-1,所以我们很少会用到这个函数。
resize() // 改变实际元素的个数。
capacity()// 返回当前容量。
empty() // 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
reserve() // 增加容器的容量。
shrink _to_fit() // 将内存减少到等于当前元素实际所使用的大小。
operator[ ] // 重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。
at() // 使用经过边界检查的索引访问元素。
swap() // 交换两个容器的所有元素。
emplace() // 在指定的位置直接生成一个元素。
emplace_back() // 在序列尾部生成一个元素。
</code></pre>
</li>
<li>
<p>哈希表</p>
<p>头文件 <code>&lt;unordered_map&gt;</code> ,在 std 名命名空间中。它将数据存储为键值对,其中键是唯一的。 声明和初始化:</p>
<pre><code class="language-c++">unordered_map&lt;string, int&gt; map1
</code></pre>
</li>
</ol>
</content>
<category term="C++" scheme="http://yuanmxc.site/categories/C/" />
<updated>2024-03-26T11:49:10.133Z</updated>
</entry>
<entry>
<id>http://yuanmxc.site/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E7%AE%97%E6%B3%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</id>
<title>算法学习笔记</title>
<link rel="alternate" href="http://yuanmxc.site/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%92%8C%E7%AE%97%E6%B3%95/%E7%AE%97%E6%B3%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<content type="html"><h2 id="总览"><a class="anchor" href="#总览">#</a> 总览</h2>
<p><strong>7 个数据结构</strong>:</p>
<ul>
<li>数组</li>
<li>链表</li>
<li>栈</li>
<li>队列</li>
<li>哈希表</li>
<li>二叉树</li>
<li>堆</li>
</ul>
<p><strong>10 个算法</strong>:</p>
<ul>
<li>递归</li>
<li>排序</li>
<li>二分查找</li>
<li>搜索</li>
<li>哈希算法</li>
<li>贪心算法</li>
<li>分治算法</li>
<li>回溯算法</li>
<li>动态规划</li>
<li>字符串匹配算法</li>
</ul>
<h2 id="数据结构的基本操作"><a class="anchor" href="#数据结构的基本操作">#</a> 数据结构的基本操作</h2>
<p>数据结构的基本操作包括:增删查改,即遍历和访问。</p>
<p>数据结构的遍历和访问的两种形式:线性、非线性,线性以 for/while 迭代为代表,非线性以递归为代表。</p>
<ol>
<li>
<p>数组遍历框架(线性迭代):</p>
<pre><code class="language-c++">void traverse(vector&lt;int&gt; arr)&#123;
for(int i = 0; i &lt; arr.size(); i++)&#123;
// 迭代访问每个元素arr[i]
&#125;