- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个进程必须按需创建和关闭线程。
每个线程使用 open2 派生一个新进程。有时在长时间执行程序后,open2有时无法 fork 进程并给出“无法分配内存错误”,有时线程也会发生这种情况。我知道Linux有软硬限制但并发数我的服务器的线程和进程不超过这些值。
是否有类似进程和线程数量的计数器,可以在一段时间后消除线程和进程的创建?
如果是这样,像 Postgres 这样的服务器如何长期工作?该项目有多个使用 TCP 进行通信的进程,但导致我在 mplayer 前端描述的错误的部分是用 Perl 编写的。代码如下:
use strict;
use warnings;
use IO::Socket::INET;
use IO::Select;
use POSIX ":sys_wait_h";
use IPC::Open2;
use 5.010;
use Config;
BEGIN
{
if(!$Config{useithreads})
{
die "Your perl does not compiled with threading support.";
}
}
use threads;
use threads::shared;
use constant
{
SERVER_PORT=>5000,
#Remote request packet fields
PACKET_REQTYPE=>0,
PACKET_FILENAM=>1,
PACKET_VOLMLVL=>2,
PACKET_ENDPOSI=>3,
PACKET_SEEKPOS=>4,
#our request typs
PLAY_REQUEST=>1,
STOP_REQUEST=>2,
INFO_REQUEST=>3,
VOCH_REQUEST=>4,
PAUS_REQUEST=>5,
PLPA_REQUEST=>6,
SEEK_REQUEST=>7,
#Play states
STATE_PAUS=>0,
STATE_PLAY=>1,
STATE_STOP=>2,
};
#The following line must be added because of a bad behavior in the perl thread library that causes a SIGPIPE to be generated under heavy usage of the threads.
$SIG{PIPE} = 'IGNORE';
#This variable holds the server socket object
my $server_socket;
#This array is used to hold objects of our all threads
my @thread_objects;
#create the server socket
$server_socket=IO::Socket::INET->new(LocalPort=>SERVER_PORT,Listen=>20,Proto=>'tcp',Reuse=>1) or
die "Creating socket error ($@)";
#Now try to accept remote connections
print "Server socket created successfully now try to accept remote connections on port: ".SERVER_PORT."\n";
while(my $client_connection=$server_socket->accept())
{
push @thread_objects,threads->create(\&player_thread,$client_connection);
$thread_objects[$#thread_objects]->detach();
}
#This subroutine is used to play something using tcp-based commands
sub player_thread
{
my $client_socket=shift;
#create a new select object
my $selector=IO::Select->new($client_socket);
#this variabe is used to pars our request
my @remote_request;
#getting th thread id of the current thread
my $tid=threads->self()->tid;
#This variable is used to hold the pid of mplayer child
my $mp_pid=-1;
#Mplayer stdin and stdout file descriptors
my ($MP_STDIN,$MP_STDOUT);
#This variable is used to check if we are playing something now or not
my $is_playing=STATE_STOP;
print "Client thread $tid created.\n";
while(1)
{
#check to see if we can read anything from our handler
#print "Before select\n";
#my @ready=$selector->can_read();
#print "After select: @ready\n";
#now the data is ready for reading so we read it here
my $data=<$client_socket>;
#This means if the connection is closed by the remote end
if(!defined($data))
{
print "Remote connection has been closed in thread $tid mplayer id is: $mp_pid and state is: $is_playing.\n";
#if we have an mplayer child when remote connection is closed we must wait for it
#so that is work is done
if($mp_pid!=-1 and $is_playing ==STATE_PLAY)
{
waitpid $mp_pid,0;
$is_playing=STATE_STOP;
}
elsif($is_playing==STATE_PAUS and $mp_pid!=-1)
{
print "thread $tid is in the paused state, we must kill mplayer.\n";
print $MP_STDIN "quit\n";
waitpid $mp_pid,0;
$is_playing=STATE_STOP;
}
last;
}#if
#FIXME:: Here we must validate our argument
#Now we try to execute the command
chomp($data);
@remote_request=split ",",$data;
print "@remote_request\n";
#Trying to reap the death child and change the state of the thread
my $dead_child=-1;
$dead_child=&reaper($mp_pid);
if($dead_child)
{
$is_playing=STATE_STOP;
$mp_pid=-1;
}
given($remote_request[PACKET_REQTYPE])
{
when($_==PLAY_REQUEST)
{
print "Play request\n";
if($is_playing==STATE_STOP)
{
eval{$mp_pid=open2($MP_STDOUT,$MP_STDIN,"mplayer -slave -really-quiet -softvol -volume ".$remote_request[PACKET_VOLMLVL]." -endpos ".$remote_request[PACKET_ENDPOSI]." ./".$remote_request[PACKET_FILENAM]);};
print "Some error occurred in open2 system call: $@\n" if $@;
$is_playing=STATE_PLAY;
print "Mplayer pid: $mp_pid.\n";
}
}
when($_==STOP_REQUEST)
{
print "Stop request\n";
if($is_playing != STATE_STOP)
{
print $MP_STDIN "pausing_keep stop\n";
#FIXME:: Maybe we should use WNOHANG here
my $id=waitpid $mp_pid,0;
print "Mplayer($id) stopped.\n";
$is_playing=STATE_STOP;
$mp_pid=-1;
}
}
when($_==PAUS_REQUEST)
{
print "pause request\n";
if($is_playing !=STATE_STOP)
{
print $MP_STDIN "pausing_keep pause\n";
$is_playing=STATE_PAUS;
}
}
when($_==VOCH_REQUEST)
{
print "volume change request\n";
if($is_playing !=STATE_STOP)
{
print $MP_STDIN "pausing_keep volume ".$remote_request[PACKET_VOLMLVL]." 1\n";
}
}
when($_==INFO_REQUEST)
{
my $id;
$id=&reaper($mp_pid);
if($id > 0)
{
print "Mplayer($id) stopped.\n";
$is_playing=STATE_STOP;
$mp_pid=-1;
}
given($is_playing)
{
when($_==STATE_STOP)
{
print $client_socket "Stopped\n";
}
when($_==STATE_PAUS)
{
print $client_socket "Paused\n";
}
when($_==STATE_PLAY)
{
print $client_socket "Playing\n";
}
}
}
when ($_==PLPA_REQUEST)
{
print "play paused request\n";
if($is_playing==STATE_STOP)
{
eval{$mp_pid=open2($MP_STDOUT,$MP_STDIN,"mplayer -slave -really-quiet -softvol -volume ".$remote_request[PACKET_VOLMLVL]." -endpos ".$remote_request[PACKET_ENDPOSI]." ./".$remote_request[PACKET_FILENAM]);};
print "Some error occurred in open2 system call: $@\n" if $@;
print $MP_STDIN "pausing_keep pause\n";
$is_playing=STATE_PAUS;
}
}
when ($_==SEEK_REQUEST)
{
print "Seek request\n";
if($is_playing != STATE_STOP)
{
my $seek_pos=abs $remote_request[PACKET_SEEKPOS];
print $MP_STDIN "seek $seek_pos 2\n";
$is_playing=STATE_PLAY;
}
}
default
{
warn "Invalid request($_)!!!";
next;
}
}#Given
}#while
$client_socket->close();
print "Thread $tid is exiting now, the child mplayer pid is: $mp_pid and state is: $is_playing.\n";
}
#The following subroutine takes a pid and if that pid is grater than 0 it tries to reap it
#if it is successful returns pid of the reaped process else 0
sub reaper
{
my $pid=shift;
if($pid > 0)
{
my $id=waitpid($pid,WNOHANG);
if($id > 0)
{
return $id;
}
}
return 0;
}
最佳答案
"Can not allocate memory error"
是它所说的,要么是用户超出了它的内存配额(用 ulimit -m
检查,与 ps ux 比较
) 或者你真的内存不足(free
)。
最大用户进程的限制只是间接关联 - 如果您 fork() 更多进程然后用户的内存配额允许,fork() 将因 ENOMEM 而失败。
您可能还想看看: What are some conditions that may cause fork() or system() calls to fail on Linux?
关于linux - fork 和 waitpid 在 Linux 上失败。没有达到硬限制或软限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7565901/
我正试图找到一个基准来衡量用户愿意等待远程服务响应的时间。在我的例子中,响应是非常有用的,但不是对数据输入的业务关键验证。我想 HCI 领域一定已经在这方面做了一些工作。 如果您知道软实时响应的普遍接
这个问题在这里已经有了答案: What's the difference between SoftReference and WeakReference in Java? (12 个回答) 关闭6年前
社区维基 我不在乎声誉点,我只想要好的答案。请随意将此问题标记为社区 wiki。 上下文 我一直在研究《理性策划者》,并发现了以下观察结果: 逻辑编程非常有趣。 逻辑编程有时是违反直觉的 逻辑编程通常
我已阅读this article关于Java中不同类型的引用(强引用、软引用、弱引用、幻像引用),但我不太理解。 这些引用类型之间有什么区别?每种类型何时使用? 最佳答案 Java 提供了两种不同类型
我需要一个带有弱键或软键的并发 HashMap ,其中等式是 equals 而不是 ==。 对于此类键,Google Collection 默认选择 ==。 有没有办法覆盖这个选择?我应该如何进行?
我读了here使用下面的命令我们可以在 Linux 系统上模拟硬重启: echo 1 > /proc/sys/kernel/sysrq echo b > /proc/sysrq-trigger 但我想
我正在使用软件 I²C实现读取一组 Sensirion SHT21 传感器。我正在尝试找出一种让传感器回答以查看它们是否实际连接到设备的方法。我正在使用 Arduino,这意味着我所有的代码都是 C/
这个问题在这里已经有了答案: How do you determine using stat() whether a file is a symbolic link? (1 个回答) 关闭 9 年前
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
我一直在使用 ICS 上的 Wifi Direct API,但有点卡住了。 在 API 中,有一个名为 createGroup 的方法可以在手机上创建一个基于遗留软件的接入点。这很棒并且有效,但我似乎
当我在 ruby 中有一个数组时,我可以在其上运行 delete_if block 。问题是它从我的数组中删除了元素。我想要相同的功能,只是不对原始数组进行更改,而是返回一个删除了对象的新数组。
在 Ubuntu Virtualbox 上运行从 Windows 移植的音频应用程序时,它报告以下内容: Devices found: OpenAL Soft OpenAL Soft 40964 in
下面是我的数据库结构的简化版本(在 MVC 2 中构建一个概念验证站点,使用 Entity Framework 4 作为我的 ORM): [Stores] StoreID (PK) StoreName
我用 ESP8266 创建了一个软 AP,我通过 android 6.0 marshmallow mobile 连接到它。连接后,如果我忽略它并打开浏览器窗口打开我的网络服务器页面或使用自定义构建的应
如何应用 Three.js online editor 中所示的 PCF (SOFT) 阴影类型以 JavaScript 代码的形式发送到你的渲染器? 最佳答案 要使用该类型的阴影,您需要使用相应类型
我知道 Wifi Direct 的工作原理是在其中一台设备中创建软 AP(软件接入点)。我也知道很多 Android 支持 Wifi Direct,但 iPhone 不支持。 我的问题是:是否可以创建
我有一个在 14.04.05 LTS 上运行的 Ubuntu 服务器。 此服务器上还安装了几个 ugins mongodb 应用程序。 MongoDB版本为3.4.2 我正在尝试增加 mongodb
我是一名优秀的程序员,十分优秀!