进程间通信

进程间通信

见天写了一段爬虫代码,通过信号量控制进程数量,代码如下:

#!/usr/bin/python3
# -*- encoding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
from multiprocessing import Process, Semaphore
def worker(s, i, d):
"""
爬取页面并解析内容。
:prama s: Semaphore
:prama i: int
:prama d: dict
"""
url = f'https://coolshell.cn/category/proglanguage/webdev/page/{i}'
resp = requests.get(url)
resp.raise_for_status()
resp.encoding = resp.apparent_encoding
soup = BeautifulSoup(resp.content, 'html.parser')
for header in soup.find_all(name='h2', attrs={'class': "entry-title"}):
s.acquire()
d[header.a.string] = header.a["href"]
s.release()
if __name__ == "__main__":
d = dict()
s = Semaphore(6)
for i in range(12):
p = Process(target=worker, args=(s, i, d))
p.start()
p.join()
print(d)

运行这段代码时,冥冥中有种不详的感觉,先看下打印结果:

{}

结果貌似不是要这个东西,发生了什么,值去哪里了@_@!

先来拍错吧,先来打印下这个字典的是不是都有值。修改代码。

# 省略其他代码
soup = BeautifulSoup(resp.content, 'html.parser')
for header in soup.find_all(name='h2', attrs={'class': "entry-title"}):
s.acquire()
d[header.a.string] = header.a["href"]
s.release()
print(d)

在来瞅瞅结果:

...
{'一些文章资源和趣闻': 'https://coolshell.cn/articles/5537.html', '一些文章和各种资源': 'https://coolshell.cn/articles/5224.html', '你会做Web上的用户登录功能吗?': 'https://coolshell.cn/articles/5353.html', '国内微博和Twitter的最
大不同': 'https://coolshell.cn/articles/5247.html', 'CSS图形': 'https://coolshell.cn/articles/5164.html', '疯狂的 Web 应用开源项目': 'https://coolshell.cn/articles/5132.html', '新浪微博的XSS攻击': 'https://coolshell.cn/articles/4914.html', '开源中最好的Web开发的资源': 'https://coolshell.cn/articles/4795.html', 'HTTP幂等性概念和应用': 'https://coolshell.cn/articles/4787.html', '在Web上运行Linux': 'https://coolshell.cn/articles/4722.html'}
{'JavaMail使用': 'https://coolshell.cn/articles/4261.html', '一些有意思的文章和资源': 'https://coolshell.cn/articles/4220.html', 'WSDL 1.1 中文规范': 'https://coolshell.cn/articles/4131.html', '另类UX让你输入强口令': 'https://coolshell.cn/articles/3877.html', '中国的C2C模式': 'https://coolshell.cn/articles/3820.html', 'Web开发人员速查卡': 'https://coolshell.cn/articles/3684.html', '为什么中国的网页设计那么烂?': 'https://coolshell.cn/articles/3605.html', 'SOAP的S是Simple': 'https://coolshell.cn/articles/3585.html', 'HTML5 logo 发布': 'https://coolshell.cn/articles/3561.html', 'JS游戏引擎列表': 'https://coolshell.cn/articles/3516.html'}
...
{}

嗯?!怎么都有值,就外边的d没值!!!

在看下这个d变量。

soup = BeautifulSoup(resp.content, 'html.parser')
for header in soup.find_all(name='h2', attrs={'class': "entry-title"}):
s.acquire()
d[header.a.string] = header.a["href"]
s.release()
print(id(d))
# ...
if __name__ == "__main__":
d = dict()
s = Semaphore(6)
for i in range(12):
p = Process(target=worker, args=(s, i, d))
p.start()
p.join()
print(id(d))

在看结果:

1485591683544
1884496142968
2362831675864
1929019801912
1779789406600
2350877778392
2435721404968
2861021733496
1868518334856
1209264906712
2248052253304
2603361968680
2417997258008

每个进程重新生成了一个d-_-!。在上边的额基础上再修改下,拿下全局变量。

soup = BeautifulSoup(resp.content, 'html.parser')
for header in soup.find_all(name='h2', attrs={'class': "entry-title"}):
s.acquire()
global d
d[header.a.string] = header.a["href"]
s.release()
print(id(d))

继续杠!

File ".\multWebDev.py", line 24
global d
^
SyntaxError: name 'd' is parameter and global

这又是什么坑@_@!

其实这个原因是由于:进程间的数据是隔离的,进程间通信,普通变量不靠谱,也不能实现进程间通信,而多线程就不存在这个问题。

进程间的通信方式有以下几种:

  1. 队列
  2. 管道
  3. 共享内存
posted @   咕咚!  阅读(187)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示