集团主站
欢迎来到成都达内官方网站!达内—美国上市公司 亿元级外企IT培训企业!
成都it培训哪家好
成都it培训哪家好
全国服务监督电话:15023458194  |   联系客服   |
当前位置:主页 > 培训课程 > Java >

成都Java培训分享关于Java并发编程的12个问题(二)

发布者: 成都达内     浏览次数:     发布时间:2018-09-11 14:58:14

接上篇:成都Java培训分享关于Java并发编程的12个问题(二)...

  接上篇:成都Java培训分享关于Java并发编程的12个问题(二)

  想了解成都Java薪资待遇?成都Java工程师前景?成都java培训机构排名?想知道成都java工程师培训哪家好?成为成都java程序员有哪些难点?关注成都达内Java培训机构cd.java.tedu.cn,你想了解的,就是我们所推送的!

  7、请问multiprocessing模块中的Value、Array类的作用是什么?举例说明它们的使用场景

  通常,进程之间彼此是完全孤立的,唯一的通信方式是队列或者管道,但是可以使用两个对象来表示共享数据。其实这些对象使用了共享内存(通过mmap模块)使访问多个进程成为可能。

  Value( typecode, arg1, … argN, lock )

  在共享内容中常见ctypes对象。typecode要么是包含array模块使用的相同类型代码

  (如’i’,’d’等)的字符串,要么是来自ctypes模块的类型对象(如ctypes.c_int、ctypes.c_double等)。

  所有额外的位置参数arg1, arg2 ….. argN将传递给指定类型的构造函数。lock是只能使用关键字调用的参数,如果把它置为True(默认值),将创建一个新的锁定来包含对值的访问。如果传入一个现有锁定,比如Lock或RLock实例,该锁定将用于进行同步。如果v是Value创建的共享值的实例,便可使用v.value访问底层的值。例如,读取v.value将获取值,而赋值v.value将修改值。

  RawValue( typecode, arg1, … ,argN)

  同Value对象,但不存在锁定。

  Array( typecode, initializer, lock )

  在共享内存中创建ctypes数组。typecode描述了数组的内容,意义与Value()函数中的相同。initializer要么是设置数组初始大小的整数,要么是项目序列,其值和大小用于初始化数组。lock是只能使用关键字调用的参数,意义与Value()函数中相同。如果a是Array创建的共享数组的实例,便可使用标准的python索引、切片和迭代操作访问它的内容,其中每种操作均由锁定进行同步。对于字节字符串,a还具有a.value属性,可以吧整个数组当做一个字符串进行访问。

  RawArray(typecode, initializer )

  同Array对象,但不存在锁定。当所编写的程序必须一次性操作大量的数组项时,如果同时使用这种数据类型和用于同步的单独锁定(如果需要的话),性能将得到极大的提升。

  应该注意,使用多进程后,通常不必再担心与锁定、信号量或类似构造的底层同步,这一点与线程不相伯仲。在某种程度上,管道上的send()和receive()操作,以及队列上的put()和get()操作已经提供了同步功能。但是,在某写特定的设置下还是需要用到共享值和锁定。下面这个例子说明了如何使用共享数组代替管道,将一个浮点数的python列表发送给另一个进程:

  import multiprocessing

  class FloatChannel(object):

  def __init__(self,maxsize):

  self.buffer=multiprocessing.RawArray('d',maxsize)

  self.buffer_len=multiprocessing.Value('i')

  self.empty=multiprocessing.Semaphore(1)

  self.full=multiprocessing.Semaphore(0)

  def send(self,values):

  self.empty.acquire() #只在缓存为空时继续

  nitems=len(values)

  self.buffer_len=nitems #设置缓冲区大小

  self.buffer[:nitems]=values #将复制到缓冲区中

  self.full.release() #发信号通知缓冲区已满

  def recv(self):

  self.full.acquire() #只在缓冲区已满时继续

  values=self.buffer[:self.buffer_len.value] #复制值

  self.empty.release() #发送信号通知缓冲区为空

  return values

  #性能测试 接收多条消息

  def consume_test(count,ch):

  for i in xrange(count):

  values=ch.recv()

  #性能测试 发送多条消息

  def produce_test(count,values,ch):

  for i in xrange(count):

  ch.send(values)

  if __name__=="__main__":

  ch=FloatChannel(100000)

  p=multiprocessing.Process(target=consume_test,args=(1000,ch))

  p.start()

  values=[float(x) for x in xrange(100000)]

  produce_test(1000,values,ch)

  print "Done"

  p.join()

  8、请问multiprocessing模块中的Manager类的作用是什么?与Value和Array类相比,Manager的优缺点是什么?

  可以通过使用Value或者Array把数据存储在一个共享的内存表中;Manager()返回一个manager类型,控制一个server process,可以允许其它进程通过代理复制一些python objects 支持list,dict,Namespace,Lock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value,Array ;

  Manager类的作用共享资源,manger的的优点是可以在poor进程池中使用,缺点是windows下环境下性能比较差,因为windows平台需要把Manager.list放在if name =' main '下,而在实例化子进程时,必须把Manager对象传递给子进程,否则lists无法被共享,而这个过程会消耗巨大资源,因此性能很差。

  multiprocessing 是一个使用方法类似threading模块的进程模块。允许程序员做并行开发。并且可以在UNIX和Windows下运行。

  通过创建一个Process 类型并且通过调用call()方法spawn一个进程。

  一个比较简单的例子:

  from multiprocessing import Process

  import time

  def f(name):

  time.sleep(1)

  print 'hello ',name

  print os.getppid() #取得父进程ID

  print os.getpid() #取得进程ID

  process_list = []

  if __name__ == '__main__':

  for i in range(10):

  p = Process(target=f,args=(i,))

  p.start()

  process_list.append(p)

  for j in process_list:

  j.join()

  进程间通信:成都Java培训班:有两种主要的方式:Queue、Pipe1- Queue类几乎就是Queue.Queue的复制,示例:

  from multiprocessing import Process,Queue

  import time

  def f(name):

  time.sleep(1)

  q.put(['hello'+str(name)])

  process_list = []

  q = Queue()

  if __name__ == '__main__':

  for i in range(10):

  p = Process(target=f,args=(i,))

  p.start()

  process_list.append(p)

  for j in process_list:

  j.join()

  for i in range(10):

  print q.get()

  2- Pipe 管道

  from multiprocessing import Process,Pipe

  import time

  import os

  def f(conn,name):

  time.sleep(1)

  conn.send(['hello'+str(name)])

  print os.getppid(),'-----------',os.getpid()

  process_list = []

  parent_conn,child_conn = Pipe()

  if __name__ == '__main__':

  for i in range(10):

  p = Process(target=f,args=(child_conn,i))

  p.start()

  process_list.append(p)

  for j in process_list:

  j.join()

  for p in range(10):

  print parent_conn.recv()

  Pipe()返回两个连接类,代表两个方向。如果两个进程在管道的两边同时读或同时写,会有可能造成corruption.

  进程间同步

  multiprocessing contains equivalents of all the synchronization primitives from threading.

  例如,可以加一个锁,以使某一时刻只有一个进程print

  from multiprocessing import Process,Lock

  import time

  import os

  def f(name):

  lock.acquire()

  time.sleep(1)

  print 'hello--'+str(name)

  print os.getppid(),'-----------',os.getpid()

  lock.release()

  process_list = []

  lock = Lock()

  if __name__ == '__main__':

  for i in range(10):

  p = Process(target=f,args=(i,))

  p.start()

  process_list.append(p)

  for j in process_list:

  j.join()

  进程间共享状态 Sharing state between processes

  当然尽最大可能防止使用共享状态,但最终有可能会使用到.

  1-共享内存

  可以通过使用Value或者Array把数据存储在一个共享的内存表中

  from multiprocessing import Process,Value,Array

  import time

  import os

  def f(n,a,name):

  time.sleep(1)

  n.value = name * name

  for i in range(len(a)):

  a[i] = -i

  process_list = []

  if __name__ == '__main__':

  num = Value('d',0.0)

  arr = Array('i',range(10))

  for i in range(10):

  p = Process(target=f,args=(num,arr,i))

  p.start()

  process_list.append(p)

  for j in process_list:

  j.join()

  print num.value

  print arr[:]

  输出:

  james@James:~/projects$ python pp.py

  81.0

  [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

  'd'和'i'参数是num和arr用来设置类型,d表示一个双精浮点类型,i表示一个带符号的整型。

  更加灵活的共享内存可以使用multiprocessing.sharectypes模块

  Server process

  Manager()返回一个manager类型,控制一个server process,可以允许其它进程通过代理复制一些python objects

  支持list,dict,Namespace,Lock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value,Array

  from multiprocessing import Process,Manager

  import time

  import os

  def f(d,name):

  time.sleep(1)

  d[name] = name * name

  print d

  process_list = []

  if __name__ == '__main__':

  manager = Manager()

  d = manager.dict()

  for i in range(10):

  p = Process(target=f,args=(d,i))

  p.start()

  process_list.append(p)

  for j in process_list:

  j.join()

  print d

  输出结果:

  {2: 4}

  {2: 4, 3: 9}

  {2: 4, 3: 9, 4: 16}

  {1: 1, 2: 4, 3: 9, 4: 16}

  {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

  {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

  {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36}

  {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 8: 64}

  {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64}

  {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

  {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

  Server process managers比共享内存方法更加的灵活,成都Java培训机构:一个单独的manager可以被同一网络的不同计算机的多个进程共享。比共享内存更加的缓慢

  使用工作池Using a pool of workers

  Pool类代表 a pool of worker processes.

  It has methods which allows tasks to be offloaded to the worker processes in a few different ways.

  9、写一个程序,包含十个线程,子线程必须等待主线程sleep 10秒钟之后才执行,并打印当前时间;

  # _*_ coding: utf-8 _*_

  # 写一个程序,包含十个线程,子线程必须等待主线程sleep 10秒钟

  # 之后才执行,并打印当前时间

  from threading import Thread

  import time

  def task(name):

  print(name,time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))

  if __name__ == '__main__':

  time.sleep(2)

  for i in range(10):

  t = Thread(target=task,args=('线程 %s'%i,))

  t.start()

  10、写一个程序,包含十个线程,同时只能有五个子线程并行执行;

  # _*_ coding: utf-8 _*_

  # 10、写一个程序,包含十个线程,同时只能有五个子线程并行执行;

  from threading import Thread

  from threading import currentThread

  from concurrent.futures import ThreadPoolExecutor

  import time

  import random

  def task():

  print(currentThread().getName())

  time.sleep(random.randint(1,3))

  if __name__ == '__main__':

  pool = ThreadPoolExecutor(5)

  for i in range(10):

  pool.submit(task)

  11、写一个程序,要求用户输入用户名和密码,要求密码长度不少于6个字符,且必须以字母开头,如果密码合法,则将该密码使用md5算法加密后的十六进制概要值存入名为password.txt的文件,超过三次不合法则退出程序;

  # _*_ coding: utf-8 _*_

  # 11、写一个程序,要求用户输入用户名和密码,要求密码

  # 长度不少于6个字符,且必须以字母开头,如果密码合法,

  # 则将该密码使用md5算法加密后的十六进制概要值存入名

  # 为password.txt的文件,超过三次不合法则退出程序;

  import re

  import hashlib

  import pickle

  def func():

  count = 0

  while count<3:

  username = input("username>>>").strip()

  password = input("password>>>").strip()

  if len(password) >=6 and re.search('\A([a-z)|[A-Z])',password):

  md5_password = hashlib.md5(password.encode('utf-8')).hexdigest()

  file_obj = {'username':username,

  'passworf':md5_password}

  f = open('password.txt','ab')

  pickle.dump(file_obj,f)

  break

  else:

  print("请输入合法的密码")

  count +=1

  else:

  print("您的机会已经用完")

  if __name__ == '__main__':

  func()

  12、写一个程序,使用socketserver模块,实现一个支持同时处理多个客户端请求的服务器,要求每次启动一个新线程处理客户端请求;

  服务端:

  # _*_ coding: utf-8 _*_

  # 12、写一个程序,使用socketserver模块,

  # 实现一个支持同时处理多个客户端请求的服务器,

  # 要求每次启动一个新线程处理客户端请求;

  import socketserver

  class Handler(socketserver.BaseRequestHandler):

  def handle(self):

  while True:

  try:

  data = self.request.recv(1024)

  if not data:

  break

  print('client data',data.decode())

  self.request.send(data.upper())

  except Exception as e:

  print(e)

  break

  if __name__ == '__main__':

  server = socketserver.ThreadingTCPServer(('127.0.0.1',8888),Handler)

  server.serve_forever()

  客户端

  # _*_ coding: utf-8 _*_

  import socket

  ip_port = ('127.0.0.1',8888)

  client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

  client.connect(ip_port)

  while True:

  msg = input(">>>>").strip()

  if not msg:

  continue

  client.send(msg.encode('utf-8'))

  data = client.recv(1024)

  print(data)

  本月成都java培训免费训练营预约开始啦,专为零基础打造,学Java来成都java培训机构——成都达内。页面留言姓名+电话+课程方向,领取达内成都java培训班免费训练营名额,高薪技术,一线名师,名企就业,只要你想学,这些统统都为你备好!

  【免责声明】本文系本网编辑部分转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与管理员联系,我们会予以更改或删除相关文章,以保证您的权益!

(责任编辑:霍老师)
最新开班
  • 成都Java培训班
    免费试听名额发放中...
  • 成都C++培训班
    免费试听名额发放中...
  • 成都PHP培训班
    免费试听名额发放中...
  • 成都网络工程培训班
    免费试听名额发放中...
  • 成都Unity3D培训班
    免费试听名额发放中...
  • 成都大数据培训班
    免费试听名额发放中...
  • 成都uid培训班
    免费试听名额发放中...
  • 成都会计培训班
    免费试听名额发放中...
  • 成都Python培训班
    免费试听名额发放中...
  • 成都嵌入式培训班
    免费试听名额发放中...
  • 成都web培训班
    免费试听名额发放中...
  • 成都软件测试培训班
    免费试听名额发放中...
在线留言
提交

校区地址:绵阳市涪城区临园路东段68号富临大都会7栋3单元9层12号

联系电话:15023458194

公交路线:富乐路口凯德广场(10路;29路;3路;15路;11路;15a路;71路)

校区地址:成都市锦江区东大街紫东楼端35号明宇金融广场19楼1906室

联系电话:15023458194

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市高新区奥克斯广场蜀锦路209号一楼商铺

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都锦江区东大街芷泉街229号东方广场C座3楼303

联系电话:15023458194

公交路线:芷泉街(188路;115路;515路;236路;505路;501路;84路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市武侯区佳灵路3号红牌楼广场2号写字楼11楼1115号

联系电话:15023458194

公交路线:红牌楼东(11路;92路;100路;111路;139路;g28路;快速公交K1/K2) 地铁路线:红牌楼站(地铁3号线)

校区地址:成都市锦江区红星路二段70号四川日报大厦502-2

联系电话:15023458194

公交路线:市二医院站(6路;49路;102路;5路;37路;g92路;) 地铁路线:地铁市二医院(地铁3号线)

校区地址:成都市锦江区东大街紫东段35号明宇广场2306

联系电话:15023458194

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:四川省成都市武侯区高新科技孵化园9号园区E座7楼

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都市人民南路一段86号“城市之心”大厦26楼

联系电话:15023458194

公交路线:成都市人民南路(6路;14路;42路;72路;76路;1010路;)

校区地址:成都市高新区奥克斯广场B座1708

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

了解达内动态
关注成都达内教育公众号

首页 | 关于达内 | 课程中心 | 专家师资 | 视频教程 | 学员空间 | 校企合作 | 新闻资讯 | 就业指导 | 网站地图

2016-2025 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56