标签:pre sdl ram 运行 raise att range release java
见天写了一段爬虫代码,通过信号量控制进程数量,代码如下:
#!/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
这又是什么坑@_@!
其实这个原因是由于:进程间的数据是隔离的,进程间通信,普通变量不靠谱,也不能实现进程间通信,而多线程就不存在这个问题。
进程间的通信方式有以下几种:
标签:pre sdl ram 运行 raise att range release java
原文地址:https://www.cnblogs.com/linga/p/13138613.html