码迷,mamicode.com
首页 > 系统相关 > 详细

进程间通信

时间:2020-06-16 00:34:08      阅读:70      评论:0      收藏:0      [点我收藏+]

标签: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

这又是什么坑@_@!

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

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

  1. 队列
  2. 管道
  3. 共享内存

进程间通信

标签:pre   sdl   ram   运行   raise   att   range   release   java   

原文地址:https://www.cnblogs.com/linga/p/13138613.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!