首页系统linux多线程编程 Linux多线程通信

linux多线程编程 Linux多线程通信

编程之家2024-04-1387次浏览

一、Linux多线程通信

PIPE和FIFO用来实现进程间相互发送非常短小的、频率很高的消息;

这两种方式通常适用于两个进程间的通信。

linux多线程编程 Linux多线程通信
共享内存用来实现进程间共享的、非常庞大的、读写操作频率很高的数据(配合信号量使用);

这种方式通常适用于多进程间通信。

其他考虑用socket。这里的“其他情况”,其实是今天主要会碰到的情况:

分布式开发。

在多进程、多线程、多模块所构成的今天最常见的分布式系统开发中,

socket是第一选择

。消息队列,现在建议不要使用了----因为找不到使用它们的理由。在实际中,我个人感觉,PIPE和FIFO可以偶尔使用下,共享内存都用的不多了。在效率上说,socket有包装数据和解包数据的过程,所以理论上来说socket是没有PIPE/FIFO快,不过现在计算机上真心不计较这么一点点速度损失的。你费劲纠结半天,不如我把socket设计好了,多插一块CPU来得更划算。另外,进程间通信的数据一般来说我们都会存入数据库的,这样万一某个进程突然死掉或者整个服务器死了,也不至于丢失重要数据、便于回滚到之前的状态。从这个角度考虑,适用共享内存的情况也更少了,所以socket使用得更多。再多说一点关于共享内存的:共享内存的效率确实高,但它的重点在“共享”二字上。如果的确有好些进程共享一大块数据(如果把每个进程都看做是类的对象的话,那么共享数据就是这个类的static数据成员),那么共享内存就是一个不二的选择了。但是在面向对象的今天,我们更多的时候是多线程+锁+线程间共享数据。因此共享进程在今天使用的也越来越少了。不过,在面对一些极度追求效率的需求时,共享内存就会成为唯一的选择,比如高频交易系统。除此以外,一般是不需要特意使用共享内存的。另外,

PIPE和共享内存是不能跨LAN的

(FIFO可以但FIFO只能用于两个进程通信)

如果你的分布式系统随着需求的增加而越来越大所以你想把不同的模块放在不同机器上而你之前开发的时候用了PIPE或者共享内存,那么你将不得不对代码进行大幅修改......同时,即使FIFO可以跨越LAN,其代码的可读性、易操作性和可移植性、适应性也远没有socket大。这也就是为什么一开始说socket是第一选择的原因。最后还有个信号简单说一下。

请注意,是信号,不是信号量。

linux多线程编程 Linux多线程通信
信号量是用于同步线程间的对象的使用的(建议题主看我的答案,自认为比较通俗易懂:

semaphore和mutex的区别?-Linux-知乎

)。信号也是进程间通信的一种方式。比如在Linux系统下,一个进程正在执行时,你用键盘按Ctrl+c,就是给这个进程发送了一个信号。进程在捕捉到这个信号后会做相应的动作。虽然信号是可以自定义的,但这并不能改变信号的局限性:

不能跨LAN、信息量极其有限

。在现代的分布式系统中,通常都是

消息驱动:

即进程受到某个消息后,通过对消息的内容的分析然后做相应的动作。如果你把你的分布式系统设置成信号驱动的,这就表示你收到一个信号就要做一个动作而一个信号的本质其实就是一个数字而已。这样系统稍微大一点的话,系统将变得异常难以维护;甚至在很多时候,信号驱动是无法满足我们的需求的。因此现在我们一般也不用信号了。因此,请记住:

除非你有非常有说服力的理由,否则请用socket。

顺便给你推荐个基于socket的轻量级的消息库:ZeroMQ。

二、Linux下PHP程序使用多线程,有没有这样的可能

引言

别的语言都在一窝蜂地搞编译,搞虚拟机,搞多线程,提高效率。我们整天敲PHP代码,除了Nginx调用php-fpm拉取PHP文件的解析外,对于多线程有多少了解?

请问,PHP能不能使用多线程?如果能,怎么实现的?

linux多线程编程 Linux多线程通信

本文就带你打开这个疑问。

学习时间

这个问题的答案是肯定的,PHP可以使用多线程。我们借助于pthreads实现:

该项目提供了与基于PosixThreads的PHP兼容的多线程。

有啥亮点没?下面这些全是:

一个易于使用,快速学习的面向对象的PHP7.2线程API执行所有预定义和用户声明的方法和函数,包括闭包。包括现成的同步无限的可能性...

需要一些扩展的基础的支持,PHP7.2及以上版本,ZTSEnabled(ThreadSafety),PosixThreadsImplementation。

还有一些注意事项:

pthreads是一个面向对象的API,它提供了PHP中多线程所需的所有工具。PHP应用程序可以创建,读取,写入,执行并与线程,辅助对象和线程对象同步。警告:pthreads扩展名不能在Web服务器环境中使用。因此,PHP中的线程应仅保留给基于CLI的应用程序使用。

命令行应用脚本完全适用,这也与我们编写Bash,Python等等类似。下面举一个例子:

然后执行一次:

再执行一次:

实际运用

上面的代码是个示例性质的应用,仅仅是为了展示多线程运行。下面来一段业务代码。

该类模拟一个url请求。因为网络问题,有可能失败,或者不确定返回时间,所以适合并行。接着我们使用该类进行多网络请求并发。为了减轻系统负荷,使用微秒延时。

$t=microtime(true);

$g=newAsyncWebRequest(sprintf("",rand()*10));

实例化之后,我们发起请求:

if($g->start()){

printf("Requesttook%fsecondstostart",microtime(true)-$t);

while($g->isRunning()){

echo".";usleep(100);

}

if($g->join()){

printf("and%fsecondstofinishreceiving%dbytes\n",microtime(true)-$t,strlen($g->data));

}else

printf("and%fsecondstofinish,requestfailed\n",microtime(true)-$t);

}

其他方案

如果不用pthreads库提供的能力,该怎么写并行的多任务呢?其实PHP提供了一个popen函数,用于打开进程文件指针。

popen返回一个和fopen所返回的相同的文件指针,只不过它是单向的(只能用于读或写)并且必须用pclose来关闭。此指针可以用于fgets,fgetss和fwrite。当模式为'r',返回的文件指针等于命令的STDOUT,当模式为'w',返回的文件指针等于命令的STDIN。

直接上代码:

for($i=0;$i<10;$i++){//打开10个进程for($j=0;$j<10;$j++){$pipe[$j]=popen('script2.php','w');}//等待完成for($j=0;$j<10;++$j){pclose($pipe[$j]);}}

大家看到了实现的方法与pthreads完全不同,这段代码仍然是阻塞运行,只不过同时打开10个进程,并行运行。

并行与多线程完全不同。不过,可视作一个简单的解决方案吧。

写在最后

经过上述两种实现方法,大家应该对于多线程,多进程,并行这些概念有一些认识了。

Happycoding:_)

我是@程序员小助手,持续分享编程知识,欢迎关注。

三、多线程下linux和windows开发应注意的区别

linux下线程的实现,linux的线程编程有两个库pthread和pth,对于pthread的实现是内核方式的实现,每个线程在kernel中都有task结构与之对应,也就是说用ps命令行是可以看见多个线程,线程的调度也是由内核中的schedule进行的。再来看看Windows的多线程下linux和windows开发应注意的区别

损失函数(损失函数值一般是多少)牛顿迭代法求根c语言,c语言牛顿迭代法求方程的根