figure:last-child { margin-bottom: 0.5rem; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; }
button, input, select, textarea { color: inherit; font: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
p { line-height: inherit; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 2; }
p { orphans: 4; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px !important; }
tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 32px; }
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
.CodeMirror-linenumber { user-select: none; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
#write pre { white-space: pre-wrap; }
#write.fences-no-line-wrapping pre { white-space: pre; }
#write pre.ty-contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
.md-diagram-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
#write .md-fences.mock-cm { white-space: pre-wrap; }
.md-fences.md-fences-with-lineno { padding-left: 0px; }
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
.CodeMirror-line, twitterwidget { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: 0px 0px; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
#write .footnote-line { white-space: pre-wrap; }
@media print {
body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; }
#write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; }
.typora-export * { -webkit-print-color-adjust: exact; }
html.blink-to-pdf { font-size: 13px; }
.typora-export #write { padding-left: 32px; padding-right: 32px; padding-bottom: 0px; break-after: avoid; }
.typora-export #write::after { height: 0px; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }
p > .md-image:only-child { display: inline-block; width: 100%; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.md-math-block { width: 100%; }
.md-math-block:not(:empty)::after { display: none; }
[contenteditable="true"]:active, [contenteditable="true"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
.md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
.md-toc-h4 .md-toc-inner { margin-left: 5em; }
.md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
.md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, samp, tt { font-family: var(--monospace); }
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); }
code { text-align: left; vertical-align: initial; }
a.md-print-anchor { white-space: pre !important; border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; background: 0px 0px !important; text-decoration: initial !important; text-shadow: initial !important; }
.md-inline-math .MathJax_SVG .noError { display: none !important; }
.html-for-mac .inline-math-svg .MathJax_SVG { vertical-align: 0.2px; }
.md-math-block .MathJax_SVG_Display { text-align: center; margin: 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; overflow-y: hidden; display: block !important; }
.MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; }
.MathJax_SVG .MJX-monospace { font-family: var(--monospace); }
.MathJax_SVG .MJX-sans-serif { font-family: sans-serif; }
.MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; zoom: 90%; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; }
.MathJax_SVG * { transition: none 0s ease 0s; }
.MathJax_SVG_Display svg { vertical-align: middle !important; margin-bottom: 0px !important; margin-top: 0px !important; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="mermaid"] svg, [lang="flow"] svg { max-width: 100%; height: auto; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom: 0px; }
video { max-width: 100%; display: block; margin: 0px auto; }
iframe { max-width: 100%; width: 100%; border: none; }
.highlight td, .highlight tr { border: 0px; }

.CodeMirror { height: auto; }
.CodeMirror.cm-s-inner { background: inherit; }
.CodeMirror-scroll { overflow: auto hidden; z-index: 3; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background: inherit; white-space: nowrap; }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: 700; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: red; }
.cm-invalidchar { color: red; }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background: inherit; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: hidden; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 30px; z-index: 3; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: 0px 0px !important; border: none !important; }
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: 0px 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; overflow-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
.CodeMirror-wrap pre { overflow-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
.CodeMirror-linebackground { position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.cm-searching { background: rgba(255, 255, 0, 0.4); }
@media print {
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}

:root { --side-bar-bg-color: #fafafa; --control-text-color: #777; }
html { font-size: 16px; }
body { font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; color: rgb(51, 51, 51); line-height: 1.6; }
#write { max-width: 860px; margin: 0px auto; padding: 30px 30px 100px; }
#write > ul:first-child, #write > ol:first-child { margin-top: 30px; }
a { color: rgb(65, 131, 196); }
h1, h2, h3, h4, h5, h6 { position: relative; margin-top: 1rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; }
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; }
h1 tt, h1 code { font-size: inherit; }
h2 tt, h2 code { font-size: inherit; }
h3 tt, h3 code { font-size: inherit; }
h4 tt, h4 code { font-size: inherit; }
h5 tt, h5 code { font-size: inherit; }
h6 tt, h6 code { font-size: inherit; }
h1 { padding-bottom: 0.3em; font-size: 2.25em; line-height: 1.2; border-bottom: 1px solid rgb(238, 238, 238); }
h2 { padding-bottom: 0.3em; font-size: 1.75em; line-height: 1.225; border-bottom: 1px solid rgb(238, 238, 238); }
h3 { font-size: 1.5em; line-height: 1.43; }
h4 { font-size: 1.25em; }
h5 { font-size: 1em; }
h6 { font-size: 1em; color: rgb(119, 119, 119); }
p, blockquote, ul, ol, dl, table { margin: 0.8em 0px; }
li > ol, li > ul { margin: 0px; }
hr { height: 2px; padding: 0px; margin: 16px 0px; background-color: rgb(231, 231, 231); border: 0px none; overflow: hidden; box-sizing: content-box; }
li p.first { display: inline-block; }
ul, ol { padding-left: 30px; }
ul:first-child, ol:first-child { margin-top: 0px; }
ul:last-child, ol:last-child { margin-bottom: 0px; }
blockquote { border-left: 4px solid rgb(223, 226, 229); padding: 0px 15px; color: rgb(119, 119, 119); }
blockquote blockquote { padding-right: 0px; }
table { padding: 0px; word-break: initial; }
table tr { border-top: 1px solid rgb(223, 226, 229); margin: 0px; padding: 0px; }
table tr:nth-child(2n), thead { background-color: rgb(248, 248, 248); }
table tr th { font-weight: bold; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: rgb(223, 226, 229); border-right-color: rgb(223, 226, 229); border-left-color: rgb(223, 226, 229); border-image: initial; border-bottom-style: initial; border-bottom-color: initial; margin: 0px; padding: 6px 13px; }
table tr td { border: 1px solid rgb(223, 226, 229); margin: 0px; padding: 6px 13px; }
table tr th:first-child, table tr td:first-child { margin-top: 0px; }
table tr th:last-child, table tr td:last-child { margin-bottom: 0px; }
.CodeMirror-lines { padding-left: 4px; }
.code-tooltip { box-shadow: rgba(0, 28, 36, 0.3) 0px 1px 1px 0px; border-top: 1px solid rgb(238, 242, 242); }
.md-fences, code, tt { border: 1px solid rgb(231, 234, 237); background-color: rgb(248, 248, 248); border-radius: 3px; padding: 2px 4px 0px; font-size: 0.9em; }
code { background-color: rgb(243, 244, 244); padding: 0px 2px; }
.md-fences { margin-bottom: 15px; margin-top: 15px; padding-top: 8px; padding-bottom: 6px; }
.md-task-list-item > input { margin-left: -1.3em; }
@media print {
html { font-size: 13px; }
table, pre { break-inside: avoid; }
pre { overflow-wrap: break-word; }
}
.md-fences { background-color: rgb(248, 248, 248); }
#write pre.md-meta-block { padding: 1rem; font-size: 85%; line-height: 1.45; background-color: rgb(247, 247, 247); border: 0px; border-radius: 3px; color: rgb(119, 119, 119); margin-top: 0px !important; }
.mathjax-block > .code-tooltip { bottom: 0.375rem; }
.md-mathjax-midline { background: rgb(250, 250, 250); }
#write > h3.md-focus::before { left: -1.5625rem; top: 0.375rem; }
#write > h4.md-focus::before { left: -1.5625rem; top: 0.285714rem; }
#write > h5.md-focus::before { left: -1.5625rem; top: 0.285714rem; }
#write > h6.md-focus::before { left: -1.5625rem; top: 0.285714rem; }
.md-image > .md-meta { border-radius: 3px; padding: 2px 0px 0px 4px; font-size: 0.9em; color: inherit; }
.md-tag { color: rgb(167, 167, 167); opacity: 1; }
.md-toc { margin-top: 20px; padding-bottom: 20px; }
.sidebar-tabs { border-bottom: none; }
#typora-quick-open { border: 1px solid rgb(221, 221, 221); background-color: rgb(248, 248, 248); }
#typora-quick-open-item { background-color: rgb(250, 250, 250); border-color: rgb(254, 254, 254) rgb(229, 229, 229) rgb(229, 229, 229) rgb(238, 238, 238); border-style: solid; border-width: 1px; }
.on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); }
header, .context-menu, .megamenu-content, footer { font-family: "Segoe UI", Arial, sans-serif; }
.file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state { visibility: visible; }
.mac-seamless-mode #typora-sidebar { background-color: var(--side-bar-bg-color); }
.md-lang { color: rgb(180, 101, 77); }
.html-for-mac .context-menu { --item-hover-bg-color: #E6F0FE; }
#md-notification .btn { border: 0px; }
.dropdown-menu .divider { border-color: rgb(229, 229, 229); }
.ty-preferences .window-content { background-color: rgb(250, 250, 250); }
.ty-preferences .nav-group-item.active { color: white; background: rgb(153, 153, 153); }
-->

Python学习day39-并发编程(各种锁)

同步锁

前文的进程中我们已经了解到,锁通常被用来实现对共享资源的同步访问.为每一个共享资源创建一个Lock对象,当我们需要访问该共享资源的时候,就需要先用acquire来获取锁对象,然后执行中间内容,执行完毕之后再调用release来释放锁.

线程中的同步锁其实就类似于我们之前用的进程锁,还有一种叫法是线程的互斥锁.

另外线程中的锁还可以保证数据的安全,具体体现如下例:

 
 
 
xxxxxxxxxx
31
 
 
 
 
1
from threading import Thread, Lock
2
3
x = 0
4
mutex = Lock()
5
6
7
def task():
8
    global x
9
    for i in range(1000000):
10
        x += 1
11
12
13
if __name__ == '__main__':
14
    t1 = Thread(target=task)
15
    t2 = Thread(target=task)
16
    t3 = Thread(target=task)
17
18
    t1.start()
19
    t2.start()
20
    t3.start()
21
22
    t1.join()
23
    t2.join()
24
    t3.join()
25
26
    print(x)
27
# 这个例程的执行结果应该是大多数人没想到的,因为结果并不是所预料的3000000,而是一个小于3000000的随机值,为什么呢?
28
# 我们可以看到,这个例子开启了三个子线程,之前我们说过,线程之间的切换一般会有两种情况,一种是线程遇到了IO,第二种就是一个线程运行的时间过长的时候,就会切换至下一个要执行的线程.这个例子就是第二种情况,因为task()里面的循环太长,所以一个线程短时间内并不能执行完,所以就会在执行期间被CPU切换至别的进程,这就出现了问题!?!?
29
# 问题就是,假设当时Thread-1正在执行x+=1这个语句,刚执行完x+1,还没有赋值给原x,此时CPU切换走了,那么这次这个循环就相当于执行了,但是没有结果,x也没有增加,这就是为什么最后的值会小于我们的预定值.
30
# 当然这种概率会很小,但是随着循环量的变大,这种概率会变大大,尤其是在循环次数大于100000以上时,造成最后的数据不正确,也不安全
31
# 所以此时我们就要考虑加入同步锁,或者说互斥锁,来保证数据的安全,添加的方法也很简单,就和之前的进程锁一样,在要执行的任务的前后两端加上acquire和release就可以了
 
 

加入同步锁以后就是这样的:

 
 
 
xxxxxxxxxx
30
 
 
 
 
1
from threading import Thread, Lock
2
3
x = 0
4
mutex = Lock()
5
6
7
def task():
8
    # with mutex:# 我们也可以这么添加同步锁,可以减少代码量
9
    mutex.acquire()# 保证数据安全,取到同步锁acquire
10
    global x
11
    for i in range(1000000):
12
        x += 1
13
    mutex.release()# 释放同步锁release
14
15
16
if __name__ == '__main__':
17
    t1 = Thread(target=task)
18
    t2 = Thread(target=task)
19
    t3 = Thread(target=task)
20
21
    t1.start()
22
    t2.start()
23
    t3.start()
24
25
    t1.join()
26
    t2.join()
27
    t3.join()
28
29
    print(x)
30
# 加入同步锁以后再执行程序,我们会看到结果就不会出错了,而且是丝毫不差
 
 

死锁与递归锁

死锁问题的根源在于过度使用同步锁,其原理类似于我们之前学习模块的时候的循环导入问题,具体描述下来就是: ​两个线程: ​ 线程1拿到了锁2,想要往下执行,需要锁1 ​ 线程2拿到了锁1,想要往下执行,需要锁2 ​ 互相都拿到了对方想要往下继续运行的锁,且彼此都不会释放自己的锁,就会造成死锁

死锁实例如下:

 
 
 
xxxxxxxxxx
49
 
 
 
 
1
# 死锁问题的演示:
2
from threading import Thread, Lock
3
import time
4
5
mutex1 = Lock()   # 互斥锁,同一时间仅有一个任务可以抢到这个锁
6
mutex2 = Lock()
7
8
9
class MyThread(Thread):
10
    def run(self):
11
        self.task1()
12
        self.task2()
13
14
    def task1(self):
15
        mutex1.acquire()
16
        print(f'{self.name}抢到了 锁1')
17
        mutex2.acquire()
18
        print(f'{self.name}抢到了 锁2')
19
        mutex1.release()
20
        print(f'{self.name}释放了 锁1')
21
        mutex2.release()
22
        print(f'{self.name}释放了 锁2')
23
24
    def task2(self):
25
        mutex2.acquire()
26
        print(f'{self.name}抢到了 锁2')
27
        time.sleep(2)
28
        mutex1.acquire()
29
        print(f'{self.name}抢到了 锁1')
30
        mutex1.release()
31
        print(f'{self.name}释放了 锁1')
32
        mutex2.release()
33
        print(f'{self.name}释放了 锁2')
34
35
36
if __name__ == '__main__':
37
    for i in range(3):
38
        t = MyThread()
39
        t.start()
40
# 结果为:
41
'''
42
Thread-1抢到了 锁1
43
Thread-1抢到了 锁2
44
Thread-1释放了 锁1
45
Thread-1释放了 锁2
46
Thread-1抢到了 锁2
47
Thread-2抢到了 锁1
48
'''
49
# 到这里程序并没有结束,而是卡住了,Thread-2想抢锁2,但是锁2在Thread-1里面,而Thread-1想抢锁1,锁1在Thread-2里面,就造成了死锁
 
 

解决死锁问题比较好的一个方法就是递归锁: 递归锁: 在同一个线程内可以被多次acquire 如何释放: 递归锁内部相当于维护了一个计数器 同一个线程acquire几次,就要release几次,计数为零的时候就可以结束

加入递归锁之后的代码如下:

 
 
 
xxxxxxxxxx
71
 
 
 
 
1
# 死锁问题的解决,递归锁
2
3
from threading import Thread, Lock, RLock# RLock就是递归锁
4
import time
5
6
mutex1 = mutex2 = RLock()# 我们用RLock来替代Lock
7
8
9
class MyThread(Thread):
10
    def run(self):
11
        self.task1()
12
        self.task2()
13
14
    def task1(self):
15
        mutex1.acquire()
16
        print(f'{self.name}抢到了 锁1')
17
        mutex2.acquire()
18
        print(f'{self.name}抢到了 锁2')
19
        mutex1.release()
20
        print(f'{self.name}释放了 锁1')
21
        mutex2.release()
22
        print(f'{self.name}释放了 锁2')
23
24
    def task2(self):
25
        mutex2.acquire()
26
        print(f'{self.name}抢到了 锁2')
27
        time.sleep(1)
28
        mutex1.acquire()
29
        print(f'{self.name}抢到了 锁1')
30
        mutex1.release()
31
        print(f'{self.name}释放了 锁1')
32
        mutex2.release()
33
        print(f'{self.name}释放了 锁2')
34
35
36
if __name__ == '__main__':
37
    for i in range(3):
38
        t = MyThread()
39
        t.start()
40
        
41
# 运行结果为:
42
'''
43
Thread-1抢到了 锁1
44
Thread-1抢到了 锁2
45
Thread-1释放了 锁1
46
Thread-1释放了 锁2
47
Thread-1抢到了 锁2
48
Thread-1抢到了 锁1
49
Thread-1释放了 锁1
50
Thread-1释放了 锁2
51
Thread-2抢到了 锁1
52
Thread-2抢到了 锁2
53
Thread-2释放了 锁1
54
Thread-2释放了 锁2
55
Thread-2抢到了 锁2
56
Thread-2抢到了 锁1
57
Thread-2释放了 锁1
58
Thread-2释放了 锁2
59
Thread-3抢到了 锁1
60
Thread-3抢到了 锁2
61
Thread-3释放了 锁1
62
Thread-3释放了 锁2
63
Thread-3抢到了 锁2
64
Thread-3抢到了 锁1
65
Thread-3释放了 锁1
66
Thread-3释放了 锁2
67
68
Process finished with exit code 0
69
70
'''
71
# 从上面结果中我们可以看到,程序的执行没有卡主,而是每个进程都取到了锁,并且释放了锁,最后都运行完毕,没有报错
 
 

信号量Semaphore(带上限的锁)

Semaphore的用法和同步锁基本一致,不同的是他可以限制同时取到这个锁的线程的数量,类比到生活也许就是,给一个锁开了几个钥匙孔?

实例如下:

 
 
 
xxxxxxxxxx
66
 
 
 
 
1
from threading import Thread, Semaphore
2
import threading
3
import time
4
5
6
def task():
7
    s.acquire()
8
    print(f'{threading.currentThread().name} 在执行')
9
    time.sleep(2)
10
    s.release()
11
12
13
if __name__ == '__main__':
14
    s = Semaphore(5)# Semaphore括号里的数字就是能同时取到锁的线程的数量,也就是说这个实例中最多允许五个进程同时取到锁,进行下面的运算
15
    for i in range(20):
16
        t = Thread(target=task)
17
        t.start()
18
# 运行结果:
19
'''
20
Thread-1 在执行
21
Thread-2 在执行
22
Thread-3 在执行
23
Thread-4 在执行
24
Thread-5 在执行
25
26
27
28
29
30
Thread-6 在执行
31
Thread-7 在执行
32
Thread-8 在执行
33
Thread-9 在执行
34
Thread-10 在执行
35
36
37
38
39
40
41
Thread-11 在执行
42
Thread-12 在执行
43
Thread-13 在执行
44
Thread-14 在执行
45
Thread-15 在执行
46
47
48
49
50
51
Thread-16 在执行
52
Thread-17 在执行
53
Thread-18 在执行
54
Thread-20 在执行
55
Thread-19 在执行
56
57
58
59
60
61
62
63
Process finished with exit code 0
64
65
'''
66
# 可能你的运行结果并不太能看的出来五个线程一组,我们可以在程序运行的时候在run窗口里面一直按回车键,虽然这很蠢....但是这种方法是最直观能看得出来五个线程同时执行的方法
 
 

GIL锁

Cpython里面有一把GIL锁(全局解释器锁),GIL锁本质上是一把互斥锁 因为GIL锁,同一时刻一个进程下只有一个线程在执行,无法利用多核优势 同一个进程下, 多个线程只能并发不能并行 为什么要有GIL: 因为Cpython自带的垃圾回收机制不是线程安全的,所以要有GIL锁

分析: 假设有四个任务要处理,处理方式要体现出并发的效果 方案一:开启四个进程 方案二:开启一个进程,四个线程

下面我们用实例来证明这两个方案的不同之处:

 
 
 
x
 
 
 
 
1
# 计算密集型任务
2
def work1():
3
    res = 0
4
    for i in range(109090000):
5
        res *= i
6
# IO密集型任务
7
# def work1():
8
#     res = 0
9
#     time.sleep(5)
10
#     for i in range(2):
11
#         res *= i
12
if __name__ == '__main__':
13
    t_list = list()
14
    start = time.time()
15
    for i in range(4):
16
        t = Thread(target=work1)
17
        t_list.append(t)
18
        t.start()
19
    for j in t_list:
20
        j.join()
21
    end = time.time()
22
    print(f'线程总共的运行时间为{end - start:6.2f}')  # 计算密集型19.13s,    IO密集型,5.00s
23
    # t_list = list()
24
    # start = time.time()
25
    # for i in range(4):
26
    #     t = Process(target=work1)
27
    #     t_list.append(t)
28
    #     t.start()
29
    # for j in t_list:
30
    #     j.join()
31
    # end = time.time()
32
    # print(f'进程总共的运行时间为{end - start:6.2f}')  # 计算密集型6.49s,   IO密集型5.31s
33
    
34
    
35
# 上例中把计算密集型任务和IO密集型任务放在了一起,读者在尝试的时候可以自己手输分开,或者是分别注释其中的一半,否则会报错
36
# 从结果中我们可以看出:
37
# 计算密集型任务,线程的时间19.13s>>进程的时间6.49s
38
# 而IO密集型任务,线程的时间5.00s<进程的时间5.31s
39
40
# 再总和考虑线程和进程的成本以及切换速度,我们就可以得出以下结论:
41
42
'''
43
如果是计算密集型任务:(推荐使用多进程的方案)(比如挖矿)
44
如果是IO密集型任务:(推荐使用多线程)(比如web,后端,爬虫)
45
'''
 
 

Python学习day39-并发编程(各种锁)的更多相关文章

  1. python学习之并发编程

    目录 一.并发编程之多进程 1.multiprocessing模块介绍 2.Process类的介绍 3.Process类的使用 3.1 创建开启子进程的两种方式 3.2 获取进程pid 3.3验证进程 ...

  2. python学习之并发编程(理论部分)

    第一章 操作系统 管理控制协调计算机中硬件与软件的关系. 操作系统的作用? 第一个作用: 将一些对硬件操作的复杂丑陋的接口,变成简单美丽的接口. open函数. 第二个作用: 多个进程抢占一个(CPU ...

  3. Python学习day37-并发编程(3)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  4. Python中的并发编程

    简介 我们将一个正在运行的程序称为进程.每个进程都有它自己的系统状态,包含内存状态.打开文件列表.追踪指令执行情况的程序指针以及一个保存局部变量的调用栈.通常情况下,一个进程依照一个单序列控制流顺序执 ...

  5. Python学习day40-并发编程(终)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  6. Python学习day38-并发编程(线程)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  7. Python学习day35-并发编程(1)

    figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { position: relative; } img { max- ...

  8. 如何深入学习Java并发编程?

    在讲解深入学习Java并发编程的方法之前,先分析如下若干错误的观点和学习方法. 错误观点1:学习Java编程主要是学习多线程. 这话其实是说明了表面现象,多线程其实还真是并发编程的实现方式,但在实际高 ...

  9. python学习_数据处理编程实例(二)

    在上一节python学习_数据处理编程实例(二)的基础上数据发生了变化,文件中除了学生的成绩外,新增了学生姓名和出生年月的信息,因此将要成变成:分别根据姓名输出每个学生的无重复的前三个最好成绩和出生年 ...

随机推荐

  1. Docker学习のWindows下如何访问Docker本身的虚拟机

    获取可访问Docker守护程序的容器 docker run --privileged -it -v /var/run/docker.sock:/var/run/docker.sock jongalla ...

  2. 十个非常实用的MySQL命令

      建赟  版主 楼主   前言 今天介绍一些MySQL常用的实用命令,都是一些比较简单的命令.已经知道的朋友,就当是巩固吧,不知道的童鞋,可以好好在自己的机器上,练习下. 0. 显示数据库 命令:s ...

  3. git提交流程简述

    1.初始化:一个项目只执行一次 只要有.git隐藏文件夹就ok了 git init 或者 git clone url 2.为远程github仓库生成别名(remote-name就是远程仓库的别名)这一 ...

  4. Linux 常用命令:解压缩篇

    前言 Linux常用命令中,有很多用于对文件的压缩或解压,本文将介绍这些解压缩命令中不常见却非常实用的用法. tar tar是linux中最常用的解压缩命令.tar命令可用于处理后缀名为tar,tar ...

  5. HLS 视频加密小记

    我是在ubuntu中,安装好了 ffmpeg 加密用的 key(生成一个encrypt2.key文件) openssl rand 16 > encrypt2.key 另一个是 iv(生成一段字符 ...

  6. mysql双主热备

    先搭建mysql主从模式,主从请参考mysql 主从笔记 然后在在配置文件里添加如下配置 1 log_slave_updates= #双主热备的关键参数.默认情况下从节点从主节点中同步过来的修改事件是 ...

  7. mysql的卸载重装+导入大量数据失败的解决方案+工具执行和项目执行结果不同

    1.卸载 1>快捷键win+r输入regedit进入注册表 找到3个文件夹,全部删除 . HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Eve ...

  8. 如何在CRichEditCtrl控件中直接读如RTF格式的文件(这个是通过流的方式来读取文件)

    如何在CRichEditCtrl控件中直接读如RTF格式的文件   Inserting an RTF string using StreamIn   ------------------------- ...

  9. (转)H264--1--编码原理以及I帧B帧P帧 .

    转:http://blog.csdn.net/yangzhongxuan/article/details/8003504 ---------------------- 前言 ------------- ...

  10. JS程序的基本语法

    JS程序的基本语法 JS是区分大小写的.如:Name和name是两个变量 JS中每一条语句,一般以英文下的分号(;)结束.这个分号不是必须的.为了向PHP兼容,最好加上分号. 运算符和变量,以及操作之 ...