mg4377娱乐娱城官网_mg4377娱乐手机版_www.mg4377.com

mg4377娱乐手机版:Python完结进程同步和通讯的秘

时间:2019-06-05 17:20来源:mg4377娱乐手机版
Python中的二10二十四线程其实并不是实在的102线程,假使想要丰富地动用多核CPU的财富,在python中繁多动静供给动用多进度。Python提供了万分好用的多进程包multiprocessing,只要求定义3个

Python中的二10二十四线程其实并不是实在的102线程,假使想要丰富地动用多核CPU的财富,在python中繁多动静供给动用多进度。Python提供了万分好用的多进程包multiprocessing,只要求定义3个函数,Python会实现别的具有事务。借助那么些包,能够轻巧做到从单进度到出现实行的更改。multiprocessing帮助子进度、通讯和共享数据、实践区别样式的联合具名,提供了Process、Queue、Pipe、Lock等零件。

参考资料

 

      Python中达成socket通讯,socket通讯的服务端相比复杂,而客户端特别轻巧,所以客户端基本上都以用sockct模块达成,而服务

引例:

Python达成进程同步和通信

经过之间通信的二种艺术:
常用的措施有:
一.行使内存映射文件
二.通过共享内部存款和储蓄器DLL共享内部存款和储蓄器
三.应用SendMessage向另一经过发送WM_COPYDATA消息.

端用有大多模块能够应用。上边就说一下服务端可应用的模块。

如从前创制多进度的事例

 

 

# -*- coding:utf-8 -*-
from multiprocessing import Process,Pool
import os,time

def run_proc(name):    ##定义一个函数用于进程调用
  for i in range(5):  
    time.sleep(0.2)  #休眠0.2秒
    print 'Run child process %s (%s)' % (name, os.getpid())
#执行一次该函数共需1秒的时间

if __name__ =='__main__': #执行主进程
  print 'Run the main process (%s).' % (os.getpid())
  mainStart = time.time() #记录主进程开始的时间
  p = Pool(8)      #开辟进程池
  for i in range(16):                 #开辟14个进程
    p.apply_async(run_proc,args=('Process' str(i),))#每个进程都调用run_proc函数,
                            #args表示给该函数传递的参数。

  print 'Waiting for all subprocesses done ...'
  p.close() #关闭进程池
  p.join() #等待开辟的所有进程执行完后,主进程才继续往下执行
  print 'All subprocesses done'
  mainEnd = time.time() #记录主进程结束时间
  print 'All process ran %0.2f seconds.' % (mainEnd-mainStart) #主进程执行时间

发送WM_COPYDATA消息

比起前三种的纷纭实现来,WM_COPYDATA新闻确切是一种经济有效的一中方法.

WM_COPYDATA音信的基本点目的是允许在进度间传递只读数据。Windows在经过WM_COPYDATA新闻传递时期,不提供后续同步格局。SDK文书档案推荐用户接纳SendMessage函数,接受方在多少拷贝达成前不回来,那样发送方就相当的小概删除和改变数据:
那个函数的原型及其要用到的构造如下:
SendMessage(hwnd,WM_COPYDATA,wParam,lParam);
其中,WM_COPYDATA对应的十陆进制数为0x004A
wParam设置为涵盖数据的窗口的句柄。lParam指向三个COPYDATASTRUCT的组织:
typedef struct tagCOPYDATASTRUCT{
DWO奥德赛D dwData;//用户定义数据
DWOHighlanderD cbData;//数据大小
PVOID lpData;//指向数据的指针
}COPYDATASTRUCT;
该协会用来定义用户数据。
切切实实经过如下:

 

const int WM_COPYDATA = 0x004A;

private void button1_Click(object sender, System.EventArgs e)
{
int WINDOW_HANDLEHaval = FindWindow(null,@"接收方窗体");
if(WINDOW_HANDLER == 0)
{
}
else
{
byte[] sarr = System.Text.Encoding.Default.GetBytes(this.textBox1.Text);
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr) 100;
cds.lpData = this.textBox1.Text;
cds.cbData = len 1;
SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds);

}
}
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)] public string lpData;
}

mg4377娱乐手机版:Python完结进程同步和通讯的秘诀,Python完成进度同步和通讯。}

 

// 接收方

this.Text = "接收方窗体";

protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch(m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr =(COPYDATASTRUCT)m.GetLParam(mytype);
this.textBox1.Text =mystr.lpData;
break;
default:
base.DefWndProc(ref m);
break;
}
}
}
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)] public string lpData;

}

 

模块名 简介 使用情况
socket 最原始,最低端的模块,如果你想亲自体验socket的整个实现过程,那就用它吧 不用
SocketServer 它把socket的实现进行了很好的封装,比如server端要为每个TCP连接创建一个新的线程/进程等等,这些你不用关心,它会帮你搞定,用户的主要工作是写已连接TCP/UDP的处理方法handle() 比较常用
select 在一个线程/进程中同时监控处理多个已连接好的socket 比较常用
Twisted 很牛逼的一个模块,功能很强大,已经算是一个框架了 比较常用
其它异步框架

如gevent等

比较常用

运作结果:

共享内存

发音讯实现的C#进程间的电视发表,和行使共享内部存款和储蓄器的运用范围是例外的,共享内部存款和储蓄器适用于共享大批量数量的情景。
本小说利用了前头的1篇.net 一.一 下促成的非确定性信号量的类,在.net 一.一下达成,假如在.net 二.0 下实现的话就用不到自家的格外非确定性信号量的类了,因为这么些类在.net 二.0是提供的。

率先照旧定义非托管调用,如下:

const int INVALID_HANDLE_VALUE = -1;
const int PAGE_READWRITE = 0x04;
  //共享内部存款和储蓄器
  [DllImport("Kernel32.dll",EntryPoint="CreateFileMapping")]
  private static extern IntPtr CreateFileMapping(IntPtr hFile, //HANDLE hFile,
   UInt32 lpAttributes,//LPSECURITY_ATTRIBUTES lpAttributes,  //0
   UInt32 flProtect,//DWORD flProtect
   UInt32 dwMaximumSizeHigh,//DWORD dwMaximumSizeHigh,
   UInt32 dwMaximumSizeLow,//DWORD dwMaximumSizeLow,
   string lpName//LPCTSTR lpName
   ); 

  [DllImport("Kernel32.dll",EntryPoint="OpenFileMapping")]
  private static extern IntPtr OpenFileMapping(
   UInt32 dwDesiredAccess,//DWORD dwDesiredAccess,
   int bInheritHandle,//BOOL bInheritHandle,
   string lpName//LPCTSTR lpName
   ); 

  const int FILE_MAP_ALL_ACCESS = 0x0002;
  const int FILE_MAP_WRITE = 0x0002; 

  [DllImport("Kernel32.dll",EntryPoint="MapViewOfFile")]
  private static extern IntPtr MapViewOfFile(
   IntPtr hFileMappingObject,//HANDLE hFileMappingObject,
   UInt32 dwDesiredAccess,//DWORD dwDesiredAccess
   UInt32 dwFileOffsetHight,//DWORD dwFileOffsetHigh,
   UInt32 dwFileOffsetLow,//DWORD dwFileOffsetLow,
   UInt32 dwNumberOfBytesToMap//SIZE_T dwNumberOfBytesToMap
   ); 

  [DllImport("Kernel32.dll",EntryPoint="UnmapViewOfFile")]
  private static extern int UnmapViewOfFile(IntPtr lpBaseAddress); 

  [DllImport("Kernel32.dll",EntryPoint="CloseHandle")]
  private static extern int CloseHandle(IntPtr hObject);

下一场分别在AB五个经过中定义如下八个时域信号量及有关变量;

  private Semaphore m_Write;  //可写的功率信号
  private Semaphore m_Read;  //可读的复信号
  private IntPtr handle;     //文件句柄
  private IntPtr addr;       //共享内部存款和储蓄器地址
  uint mapLength;            //共享内部存款和储蓄器长

 

概念那八个功率信号量是为读写互斥用的。
在A进程中创制共享内部存款和储蓄器:

m_Write = new Semaphore(1,1,"WriteMap");
m_Read = new Semaphore(0,1,"ReadMap");
mapLength = 1024;
IntPtr hFile = new IntPtr(INVALID_HANDLE_VALUE);   
handle = CreateFileMapping(hFile,0,PAGE_READWRITE,0,mapLength,"shareMemory");
addr = MapViewOfFile(handle,FILE_MAP_ALL_ACCESS,0,0,0);

然后再向共享内部存款和储蓄器中写入数据:

m_Write.WaitOne();
byte[] sendStr = Encoding.Default.GetBytes(txtMsg.Text   '/0');
//假如壹旦超长的话,应其它处理,最佳是分配丰裕的内部存款和储蓄器
if(sendStr.Length < mapLength)
      Copy(sendStr,addr);
m_Read.Release();

那是在3个独门的法子中实现的,可反复调用,但受时限信号量的支配。其中txtMsg是三个文本框控件,实际中可用任性字符串,加最终的'/0'是为了让在共享内部存储器中的字符串有三个了结符,不然在内部存储器中收取时是以'/0'为准的,就能够油不过生取多的图景。
Copy方法的完毕如下:

static unsafe void Copy(byte[] byteSrc,IntPtr dst)
  {
   fixed (byte* pSrc = byteSrc)
   {
    byte* pDst = (byte*)dst;
    byte* psrc = pSrc;
    for(int i=0;i<byteSrc.Length;i )
    {
     *pDst = *psrc;
     pDst ;
     psrc  ;
    }
   }
  }

 

小心unsafe 关键字,在编写翻译时必就要展开非安全代码按键。
最后不要忘了在A进度中关闭共享内部存款和储蓄器对象,避防内部存款和储蓄器泄露。

   UnmapViewOfFile(addr);
   CloseHandle(handle);

要在B进度中读取共享内部存款和储蓄器中的数据,首先要开拓共享内部存款和储蓄器对象:

m_Write = Semaphore.OpenExisting("WriteMap");
m_Read = Semaphore.OpenExisting("ReadMap");
handle = OpenFileMapping(0x0002,0,"shareMemory");

读取共享内部存款和储蓄器中的数码:

   m_Read.WaitOne();
   string str = MapViewOfFile(handle,FILE_MAP_ALL_ACCESS,0,0,0);
   txtMsg.Text = str;
   m_Write.Release();

此间获得了字符串,假诺要收获byte数组,请参照他事他说加以调查上边的Copy函数完结。

 

 

 

 

 

 

 

 

 

参照小说

c# 进度间同步完毕进度之间通信的二种艺术(转发)

 

Run the main process (36652). 
Waiting for all subprocesses done … 
Run child process Process0 (36708)Run child process Process1 (36748)

Run child process Process3 (36736) 
Run child process Process2 (36716) 
Run child process Process4 (36768)

      上面用地点多少个常用的模块达成TCP类型socket通讯:Client端发送字符串,Server端收到后在数量前加管理线程/进度的id再次来到,Client端收到后打

如第2行的出口,有的时候会油不过生这么不及意的输入格式,为啥吧?

印出来。Client端要是输入的是空字符,这就关闭Client的socket,接着结束该Client进程(它会触发Server端对应的connected_socket.recv()返回空

缘由是多个进程争用打字与印刷输出能源的结果。前一个历程为来得急输出换行符,该能源就切换给了另叁个进程使用,致使多少个进度输出在同壹行上,而前三个进度的换行符在下壹遍获得财富时才打字与印刷输出。

字符串,关闭connect_sock。以下都是在Windows上运维通过。若是想结束server或client端,那就一向kill就行了,它会自动释放占用的具有能源。

编辑:mg4377娱乐手机版 本文来源:mg4377娱乐手机版:Python完结进程同步和通讯的秘

关键词: 日记本 Python Updating 计算机网络