Python inter-process pass file descriptor extension Library

Source: Internet
Author: User

Because the python thread is basically crippled, so in order to take advantage of the machine's CPU, it will have to use many processes ...

In the design of the game server, the most common way is:

Hangs a front-end server dedicated to maintaining a connection to the client, and then forwards the client's request data to the backend server ...


The way above is now the most orthodox ...


However, because of the environmental constraints, you need to be transparent to the client, and then convert the backend server into a multi-process ... So here is only a bit more awkward method, first processing login and other general logic on the front-end server, when entered into the matching battle, the client socket connection directly to the back-end server, and then processed ...

Therefore, it is necessary to implement a Python-capable file descriptor Delivery Extension Library ....


Fortunately, I have done similar things in C language ... So basically take the code, and then use Cython to do a layer of packaging, you can use, here directly paste code it:

#include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <sys/un.h> #include <string.h> #include <unistd.h>int serv_listen (const char *name); int send_fd (int sock, int fd, char* data), int recv_fd (int sock, char *data);  void close_fd (int fd);

The above is the definition of the header file, then the C language code to paste it up:

#include "sr.h" int sr_connect (const char *name) {int fd, size;struct sockaddr_un un;memset (&un, 0, sizeof (un)); Un.sun _family = Af_unix;if ((FD = socket (Af_unix, sock_stream, 0)) < 0) {printf ("no1\n"); return 0;} sprintf (Un.sun_path, "%s%05d", "tmp", Getpid ()); size = Offsetof (struct Sockaddr_un, Sun_path) + strlen (Un.sun_path); if ( Bind (FD, (struct sockaddr *) &un, size) < 0) {printf ("no2\n"); return 0;} strcpy (Un.sun_path, name), size = Offsetof (struct Sockaddr_un, Sun_path) + strlen (Un.sun_path), if (Connect (FD, struct SOCKADDR *) &un, size) < 0) {printf ("no3\n"); return 0;} if (FD, listen) < 0) {//printf ("NO3");//}//char* hello = "Hello fjs";//ssize_t out = Send (FD, (void*) Hello, S Trlen (Hello), 0);//SEND_FD (LIS, Lis); return FD;}    int send_fd (int sock, int fd, char* data) {printf ("Here1:%s\n", data);        struct Iovec iov[1];        Iov[0].iov_base = data;    Iov[0].iov_len = strlen (data);    printf ("Len:%d\n", strlen (data)); printf ("Here2:%s\n ", iov[0].iov_base);        int cmsgsize = Cmsg_len (sizeof (int));        struct cmsghdr* cmptr = (struct cmsghdr*) malloc (cmsgsize);        if (cmptr = = NULL) {return-1;        } cmptr->cmsg_level = Sol_socket; Cmptr->cmsg_type = scm_rights;        We are sending FD.            Cmptr->cmsg_len = cmsgsize;        struct MSGHDR msg;        Msg.msg_iov = Iov;        Msg.msg_iovlen = 1;        Msg.msg_name = NULL;        Msg.msg_namelen = 0;        Msg.msg_control = cmptr;        Msg.msg_controllen = cmsgsize;                * (int *) Cmsg_data (cmptr) = FD;        int ret = sendmsg (sock, &msg, 0);        Free (CMPTR);        if (ret = =-1) {return-1;  } return 0;        } int recv_fd (int sock, char* data) {int cmsgsize = Cmsg_len (sizeof (int));        struct cmsghdr* cmptr = (struct cmsghdr*) malloc (cmsgsize);      if (cmptr = = NULL) {return-1; } Char buf[33];     The Max buf in Msg. memset (buf, 0, 33);      struct Iovec iov[1];        Iov[0].iov_base = BUF;        Iov[0].iov_len = sizeof (BUF);    struct MSGHDR msg;        Msg.msg_iov = Iov;        Msg.msg_iovlen = 1;        Msg.msg_name = NULL;        Msg.msg_namelen = 0;        Msg.msg_control = cmptr;                Msg.msg_controllen = cmsgsize;             int ret = recvmsg (sock, &msg, 0);       if (ret = =-1) {return-1;    } int fd = * (int *) Cmsg_data (CMPTR);    strcpy (data, iov[0].iov_base);     Free (CMPTR);    return FD; }void close_fd (int fd) {close (FD);} int main ()//{//int lis = Serv_listen ("/tmp/fjs.sock");//printf ("ok\n");//char* hello = "Hello fjs"///ssize_t OU t = Send (LIS, (void*) Hello, strlen (hello), 0);//SEND_FD (LIS, Lis);/}


Finally, paste the Cython packaging file:

cdef extern from "sr.h": extern int sr_connect (const char *name) extern int send_fd (int sock, int fd, char* data) extern int RECV_FD (int sock, char* data) void close_fd (int fd) cdef extern from "stdlib.h": extern void *malloc (unsigned int num_bytes) E Xtern void free (void *ptr) def connect_and_send (): cdef char* dist = "/tmp/fjs.sock" cdef int fd = sr_connect (dist) SEND_FD (FD , FD, "Fdsaf");d EF fjs_recv_fd (sock): cdef int fd = sockcdef char* data = <char*>malloc () fd = RECV_FD (fd, data) Try: Out_data = DataReturn (FD, Out_data) finally:free (data) def fjs_send_fd (FD1, FD2, data): Cdef int source = fd1cdef int Des
   = fd2send_fd (source, DES, data) def FJS_CLOSE_FD (FD): cdef int now_fd = FDCLOSE_FD (FD)


Well.. Just above the code ... This requires a UNIX-based domain socket ....


Finally spit the trough a bit .... Python is so fucking slow ....

Python inter-process pass file descriptor extension Library

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.