存档

2013年4月 的存档

Linux的errno定义

2013年4月28日 没有评论

从网上搜到的,这个东东用处很大,随时备查。
  124 EMEDIUMTYPE Wrong medium type
  123 ENOMEDIUM No medium found
  122 EDQUOT Disk quota exceeded
  121 EREMOTEIO Remote I/O error
  120 EISNAM Is a named type file
  119 ENAVAIL No XENIX semaphores available
  118 ENOTNAM Not a XENIX named type file
  117 EUCLEAN Structure needs cleaning
  116 ESTALE Stale NFS file handle
  115 EINPROGRESS +Operation now in progress
  114 EALREADY Operation already in progress
  113 EHOSTUNREACH No route to host
  112 EHOSTDOWN Host is down
  111 ECONNREFUSED Connection refused
  110 ETIMEDOUT +Connection timed out
  109 ETOOMANYREFS Too many references: cannot splice
  108 ESHUTDOWN Cannot send after transport endpoint shutdown
  107 ENOTCONN Transport endpoint is not connected
  106 EISCONN Transport endpoint is already connected
  105 ENOBUFS No buffer space available
  104 ECONNRESET Connection reset by peer
  103 ECONNABORTED Software caused connection abort
  102 ENETRESET Network dropped connection on reset
  101 ENETUNREACH Network is unreachable
  100 ENETDOWN Network is down
  99 EADDRNOTAVAIL Cannot assign requested address
  98 EADDRINUSE Address already in use
  97 EAFNOSUPPORT Address family not supported by protocol
  96 EPFNOSUPPORT Protocol family not supported
  95 EOPNOTSUPP Operation not supported
  94 ESOCKTNOSUPPORT Socket type not supported
  93 EPROTONOSUPPORT Protocol not supported
  92 ENOPROTOOPT Protocol not available
  91 EPROTOTYPE Protocol wrong type for socket
  90 EMSGSIZE +Message too long
  89 EDESTADDRREQ Destination address required
  88 ENOTSOCK Socket operation on non-socket
  87 EUSERS Too many users
  86 ESTRPIPE Streams pipe error
  85 ERESTART Interrupted system call should be restarted
  84 EILSEQ Invalid or incomplete multibyte or wide character
  83 ELIBEXEC Cannot exec a shared library directly
  82 ELIBMAX Attempting to link in too many shared libraries
  81 ELIBSCN .lib section in a.out corrupted
  80 ELIBBAD Accessing a corrupted shared library
  79 ELIBACC Can not access a needed shared library
  78 EREMCHG Remote address changed
  77 EBADFD File descriptor in bad state
  76 ENOTUNIQ Name not unique on network
  75 EOVERFLOW Value too large for defined data type
  74 EBADMSG +Bad message
  73 EDOTDOT RFS specific error
  72 EMULTIHOP Multihop attempted
  71 EPROTO Protocol error
  70 ECOMM Communication error on send
  69 ESRMNT Srmount error
  68 EADV Advertise error
  67 ENOLINK Link has been severed
  66 EREMOTE Object is remote
  65 ENOPKG Package not installed
  64 ENONET Machine is not on the network
  63 ENOSR Out of streams resources
  62 ETIME Timer expired
  61 ENODATA No data available
  60 ENOSTR Device not a stream
  59 EBFONT Bad font file format
  57 EBADSLT Invalid slot
  56 EBADRQC Invalid request code
  55 ENOANO No anode
  54 EXFULL Exchange full
  53 EBADR Invalid request descriptor
  52 EBADE Invalid exchange
  51 EL2HLT Level 2 halted
  50 ENOCSI No CSI structure available
  49 EUNATCH Protocol driver not attached
  48 ELNRNG Link number out of range
  47 EL3RST Level 3 reset
  46 EL3HLT Level 3 halted
  45 EL2NSYNC Level 2 not synchronized
  44 ECHRNG Channel number out of range
  43 EIDRM Identifier removed
  42 ENOMSG No message of desired type
  40 ELOOP Too many levels of symbolic links
  39 ENOTEMPTY +Directory not empty
  38 ENOSYS +Function not implemented
  37 ENOLCK +No locks available
  36 ENAMETOOLONG +File name too long
  35 EDEADLK +Resource deadlock avoided
  34 ERANGE +Numerical result out of range
  33 EDOM +Numerical argument out of domain
  32 EPIPE +Broken pipe
  31 EMLINK +Too many links
  30 EROFS +Read-only file system
  29 ESPIPE +Illegal seek
  28 ENOSPC +No space left on device
  27 EFBIG +File too large
  26 ETXTBSY Text file busy
  25 ENOTTY +Inappropriate ioctl for device
  24 EMFILE +Too many open files
  23 ENFILE +Too many open files in system
  22 EINVAL +Invalid argument
  21 EISDIR +Is a directory
  20 ENOTDIR +Not a directory
  19 ENODEV +No such device
  18 EXDEV +Invalid cross-device link
  17 EEXIST +File exists
  16 EBUSY +Device or resource busy
  15 ENOTBLK Block device required
  14 EFAULT +Bad address
  13 EACCES +Permission denied
  12 ENOMEM +Cannot allocate memory
  11 EAGAIN +Resource temporarily unavailable
  10 ECHILD +No child processes
  9 EBADF +Bad file descriptor
  8 ENOEXEC +Exec format error
  7 E2BIG +Argument list too long
  6 ENXIO +No such device or address
  5 EIO +Input/output error
  4 EINTR +Interrupted system call
  3 ESRCH +No such process
  2 ENOENT +No such file or directory
  1 EPERM +Operation not permitted
  0 Success

分类: C/C++ 标签:

PHP进程间通信IPC-消息队列的使用

2013年4月25日 1 条评论

Linux IPC消息队列是一个全内存设计,内核保证读写顺序和数据同步,并且性能非常强悍的先进现先出数据结构。它的特性如下:

  1. 每秒可读写超过50万次(4核/4G内存的机器)
  2. 支持消息多类型,抢队列时可根据需要获取特定的消息类型
  3. 每个消息长度最大支持65535个字节
  4. 队列长度受内存大小限制,最大不超过机器内存的50%,可以修改内核参数来调整

消息队列可以用在很多场景下,如异步任务处理,抢占式的数据分发,顺序缓存区等。使用方法也非常简单,Linux提供了4个库函数,msgget,msgsnd,msgrcv,msgctl,分别用于创建/获取消息队列、发送数据、接收数据、设置/获取消息队列。PHP内核包含了这个扩展,需要在./configure时加入–enable-sysvmsg来开启。具体可参考PHP手册。Swoole框架内提供了一个sysvmsg的封装,代码在http://code.google.com/p/swoole/source/browse/trunk/libs/class/swoole/queue/SysvQueue.class.php.

下面写一个简单的例子,采用单Proxy主进程+多Worker进程的模式,功能是做异步任务的处理。本代码没有提供进程管理、信号处理、队列过载保护,如果要用在生产环境,请自行实现。


<?php
$msg_key = 0x3000111; //系统消息队列的key
$worker_num = 2;   //启动的Worker进程数量
$worker_pid = array();

$queue = msg_get_queue($msg_key, 0666);
if($queue === false)
{
    die("create queue fail\n");
}
for($i = 0; $i < $worker_num; $i++)
{
    $pid = pcntl_fork();
    //主进程
    if($pid > 0)
    {
        $worker_pid[] = $pid;
        echo "create worker $i.pid = $pid\n";
        continue;
    }
    //子进程
    elseif($pid == 0)
    {
        proc_worker($i);
        exit;
    }
    else
    {
        echo "fork fail\n";
    }
}

proc_main();

function proc_main()
{
    global $queue;
    $bind = "udp://0.0.0.0:9999";
    //建立一个UDP服务器接收请求
    $socket = stream_socket_server($bind, $errno, $errstr, STREAM_SERVER_BIND);
    if (!$socket)
    {
        die("$errstr ($errno)");
    }
    stream_set_blocking($socket, 1);
    echo "stream_socket_server bind=$bind\n";
    while (1)
    {
        $errCode = 0;
        $peer = '';
        $pkt = stream_socket_recvfrom($socket, 8192, 0, $peer);

        if($pkt == false)
        {
            echo "udp error\n";
        }
        $ret = msg_send($queue, 1, $pkt, false, true, $errCode); //如果队列满了,这里会阻塞
        if($ret)
        {
            stream_socket_sendto($socket, "OK\n", 0, $peer);
        }
        else
        {
            stream_socket_sendto($socket, "ER\n", 0, $peer);
        }
    }
}

function proc_worker($id)
{
    global $queue;
    $msg_type = 0;
    $msg_pkt = '';
    $errCode = 0;
    while(1)
    {
        $ret = msg_receive($queue, 0, $msg_type, 8192, $msg_pkt, false, $errCode);
        if($ret)
        {
            //TODO 这里处理接收到的数据
            //.... Code ....//
            echo "[Worker $id] ".$msg_pkt;
        }
        else
        {
            echo "ERROR: queue errno={$errCode}\n";
        }
    }
}

运行结果:

create worker 0.pid = 18885
create worker 1.pid = 18886
stream_socket_server bind=udp://0.0.0.0:9999
[Worker 0] hello
[Worker 1] hello2
[Worker 0] hello1

客户端使用netcat来测试,netcat -u 127.0.0.1 9999。

使用ipcs -q来查看系统消息队列:

tianfenghan@VM_194_118_sles10_64:/data/nginx_log> ipcs -q

------ Message Queues --------
key msqid owner perms used-bytes messages
0x4000270f 0 tianfengha 666 0 0
0x03000111 32769 tianfengha 666 0 0

0×03000111就是刚才我们创建的消息队列。

分类: PHP 标签: