zoukankan      html  css  js  c++  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. 共享内存
  • 相关阅读:
    Windows设置VMware开机自动启动,虚拟机也启动
    PHP中unset,array_splice删除数组中元素的区别
    Linux 出现 E325:ATTENTION swap
    Linux中的info指令
    java创建线程的三种方式——附源码说明
    JVM类加载过程
    java实现责任链模式的小demo
    讲讲java中线程池的实现
    将原型模式和建造者模式结合起来耍一耍
    一个简单的单例模式Demo
  • 原文地址:https://www.cnblogs.com/linga/p/13138613.html
Copyright © 2011-2022 走看看