问下互锁电路图的事

您现在的位置: -->
--> Jetty线程“互锁”导致数据传输性能降低问题分析
Jetty线程“互锁”导致数据传输性能降低问题分析
& &以下分析针对jetty的特定版本: & &首先介绍一下Jetty的反映器模型,Jetty用的经典的NIO异步模型(Scalable IO in Java )。连接管理的示意图如下: & & & &Jetty在使用这个模型的时候,做了一些改动,acceptor是独立出来的一个阻塞线程,用于阻塞地接受新的连接请求,而所有的连接建立之后,都会想selector线程注册网络事件和内部的事件(changes),selector需要同时处理网络事件和内部的changes。同时还要定期检查超时的链接。 & &当一个连接建立之后,除了分发网络事件之外,主线程还会与子线程有一些交互。当子线程发现网络拥塞,缓冲区的数据无法及时刷走时,会注册一个表明自己处于阻塞状态的内部事件,并且期望主线程在发现拥塞解除的时候能通知到自己。 & &具体的代码如下:/* ------------------------------------------------------------ */ & &/* & & * Allows thread to block waiting for further events. & & */ & &@Override & &public boolean blockWritable(long timeoutMs) throws IOException & &{ & & & &synchronized (this) & & & &{ & & & & & &long start=_selectSet.getNow(); & & & & & &try & & & & & &{ &
& & & & & & & &_writeBlocked= & & & & & & & &while (isOpen() && _writeBlocked) & & & & & & & &{ & & & & & & & & & &try & & & & & & & & & &{ & & & & & & & & & & & &updateKey(); & & & & & & & & & & & &this.wait(timeoutMs); & & & & & & & & & & & &timeoutMs -= _selectSet.getNow()- & & & & & & & & & & & &if (_writeBlocked && timeoutMs&=0) & & & & & & & & & & & & & & & & & & & & & & & &} & & & & & & & & & &catch (InterruptedException e) & & & & & & & & & &{ & & & & & & & & & & & &Log.warn(e); & & & & & & & & & &} & & & & & & & &} & & & & & &} & & & & & &finally & & & & & &{ & & & & & & & &_writeBlocked= & & & & & & & &if (_idleTimestamp!=-1) & & & & & & & & & &scheduleIdle(); & & & & & &} & & & &} & & & & & &} & & & &而主线程的select主循环的代码如下:/* ------------------------------------------------------------ */ & &/** & & * Select and dispatch tasks found from changes and the selector. & & *
& & * @throws IOException & & */ & &public void doSelect() throws IOException & &{ & & & &try & & & &{ & & & & & &_selecting=Thread.currentThread(); & & & & & &final Selector selector=_ & & & & & &// Make any key changes required & & & & & &O & & & & & &int changes=_changes.size(); & & & & & &while (changes--&0 && (change=_changes.poll())!=null) & & & & & &{ & & & & & & & &try & & & & & & & &{ & & & & & & & & & &if (change instanceof EndPoint) & & & & & & & & & &{ & & & & & & & & & & & &// Update the operations for a key. & & & & & & & & & & & &SelectChannelEndPoint endpoint = (SelectChannelEndPoint) & & & & & & & & & & & &endpoint.doUpdateKey(); & & & & & & & & & &} & & & & & & & & & &else if (change instanceof ChannelAndAttachment) & & & & & & & & & &{ & & & & & & & & & & & &// finish accepting/connecting this connection & & & & & & & & & & & &final ChannelAndAttachment asc = (ChannelAndAttachment) & & & & & & & & & & & &final SelectableChannel channel=asc._ & & & & & & & & & & & &final Object att = asc._ & & & & & & & & & & & &SelectionKey key = channel.register(selector,SelectionKey.OP_READ,att); & & & & & & & & & & & &SelectChannelEndPoint endpoint = createEndPoint((SocketChannel)channel,key); & & & & & & & & & & & &key.attach(endpoint); & & & & & & & & & & & &endpoint.schedule(); & & & & & & & & & &} & & & & & & & & & &else if (change instanceof SocketChannel) & & & & & & & & & &{ & & & & & & & & & & & &// Newly registered channel & & & & & & & & & & & &final SocketChannel channel=(SocketChannel) & & & & & & & & & & & &SelectionKey key = channel.register(selector,SelectionKey.OP_READ,null); & & & & & & & & & & & &SelectChannelEndPoint endpoint = createEndPoint(channel,key); & & & & & & & & & & & &key.attach(endpoint); & & & & & & & & & & & &endpoint.schedule(); & & & & & & & & & &} & & & & & & & & & &else if (change instanceof Runnable) & & & & & & & & & &{ & & & & & & & & & & & &dispatch((Runnable)change); & & & & & & & & & &} & & & & & & & & & &else & & & & & & & & & & & &throw new IllegalArgumentException(change.toString()); & & & & & & & &} & & & & & & & &catch (Exception e) & & & & & & & &{ & & & & & & & & & &if (isRunning()) & & & & & & & & & & & &Log.warn(e); & & & & & & & & & &else & & & & & & & & & & & &Log.debug(e); & & & & & & & &} & & & & & & & &catch (Error e) & & & & & & & &{ & & & & & & & & & &if (isRunning()) & & & & & & & & & & & &Log.warn(e); & & & & & & & & & &else & & & & & & & & & & & &Log.debug(e); & & & & & & & &} & & & & & &} & & & & & &// Do and instant select to see if any connections can be handled. & & & & & &int selected=selector.selectNow(); & & & & & &_selects++; & & & & & &long now=System.currentTimeMillis(); & & & & & & & & & & & &// if no immediate things to do & & & & & &if (selected==0) & & & & & &{ & & & & & & & &// If we are in pausing mode & & & & & & & &if (_pausing) & & & & & & & &{ & & & & & & & & & &try & & & & & & & & & &{ & & & & & & & & & & & &Thread.sleep(__BUSY_PAUSE); // pause to reduce impact of &busy loop & & & & & & & & & &} & & & & & & & & & &catch(InterruptedException e) & & & & & & & & & &{ & & & & & & & & & & & &Log.ignore(e); & & & & & & & & & &} & & & & & & & & & &now=System.currentTimeMillis(); & & & & & & & &} & & & & & & & &// workout how long to wait in select & & & & & & & &_timeout.setNow(now); & & & & & & & &long to_next_timeout=_timeout.getTimeToNext(); & & & & & & & &long wait = _changes.size()==0?__IDLE_TICK:0L; & & & & & & & & &if (wait & 0 && to_next_timeout &= 0 && wait & to_next_timeout) & & & & & & & & & &wait = to_next_ & & & & & & & &// If we should wait with a select & & & & & & & &if (wait&0) & & & & & & & &{ & & & & & & & & & &long before= & & & & & & & & & &selected=selector.select(wait); & & & & & & & & & &_selects++; & & & & & & & & & &now = System.currentTimeMillis(); & & & & & & & & & &_timeout.setNow(now); & & & & & & & & & &checkJvmBugs(before, now, wait, selected); & & & & & & & &} & & & & & &} & & & & & & & & & & & &// have we been destroyed while sleeping & & & & & &if (_selector==null || !selector.isOpen()) & & & & & & & & & & & & & &// Look for things to do & & & & & &for (SelectionKey key: selector.selectedKeys()) & & & & & &{ &
& & & & & & & &try & & & & & & & &{ & & & & & & & & & &if (!key.isValid()) & & & & & & & & & &{ & & & & & & & & & & & &key.cancel(); & & & & & & & & & & & &SelectChannelEndPoint endpoint = (SelectChannelEndPoint)key.attachment(); & & & & & & & & & & & &if (endpoint != null) & & & & & & & & & & & & & &endpoint.doUpdateKey(); & & & & & & & & & & & & & & & & & & & & & &} & & & & & & & & & &Object att = key.attachment(); & & & & & & & & & &if (att instanceof SelectChannelEndPoint) & & & & & & & & & &{ & & & & & & & & & & & &((SelectChannelEndPoint)att).schedule(); & & & & & & & & & &} & & & & & & & & & &else & & & & & & & & & &{ & & & & & & & & & & & &// Wrap readable registered channel in an endpoint & & & & & & & & & & & &SocketChannel channel = (SocketChannel)key.channel(); & & & & & & & & & & & &SelectChannelEndPoint endpoint = createEndPoint(channel,key); & & & & & & & & & & & &key.attach(endpoint); & & & & & & & & & & & &if (key.isReadable()) & & & & & & & & & & & & & &endpoint.schedule(); & & & & & & & & & & & & &
& & & & & & & & & &} & & & & & & & & & &key = & & & & & & & &} & & & & & & & &catch (CancelledKeyException e) & & & & & & & &{ & & & & & & & & & &Log.ignore(e); & & & & & & & &} & & & & & & & &catch (Exception e) & & & & & & & &{ & & & & & & & & & &if (isRunning()) & & & & & & & & & & & &Log.warn(e); & & & & & & & & & &else & & & & & & & & & & & &Log.ignore(e); & & & & & & & & & &if (key != null && !(key.channel() instanceof ServerSocketChannel) && key.isValid()) & & & & & & & & & & & &key.cancel(); & & & & & & & &} & & & & & &} & & & & & & & & & & & &// Everything always handled & & & & & &selector.selectedKeys().clear(); & & & & & & & & & & & &now=System.currentTimeMillis(); & & & & & &_timeout.setNow(now); & & & & & &Task task = _timeout.expired(); & & & & & &while (task!=null) & & & & & &{ & & & & & & & &if (task instanceof Runnable) & & & & & & & & & &dispatch((Runnable)task); & & & & & & & &task = _timeout.expired(); & & & & & &} & & & & & &// Idle tick & & & & & &if (now-_idleTick&__IDLE_TICK) & & & & & &{ & & & & & & & &_idleTick= & & & & & & & & & & & & & & & &final long idle_now=((_lowResourcesConnections&0 && selector.keys().size()&_lowResourcesConnections)) & & & & & & & & & &?(now+_maxIdleTime-_lowResourcesMaxIdleTime) & & & & & & & & & &: & & & & & & & & & & & & & & & & & &dispatch(new Runnable() & & & & & & & &{ & & & & & & & & & &public void run() & & & & & & & & & &{ & & & & & & & & & & & &for (SelectChannelEndPoint endp:_endPoints.keySet()) & & & & & & & & & & & &{ & & & & & & & & & & & & & &endp.checkIdleTimestamp(idle_now); & & & & & & & & & & & &} & & & & & & & & & &} & & & & & & & &}); & & & & & &} & & & &} & & & &catch (CancelledKeyException e) & & & &{ & & & & & &Log.ignore(e); & & & &} & & & &finally & & & &{ & & & & & &_selecting= & & & &} & &} & &/* ------------------------------------------------------------ */ & &private void checkJvmBugs(long before, long now, long wait, int selected) & & & &throws IOException & &{ & & & &Selector selector = _ & & & &if (selector==null) & & & & & & & & & & & & & & & &// Look for JVM bugs over a monitor period. & & & &// /bugdatabase/view_bug.do?bug_id=6403933 & & & &// /view_bug.do?bug_id=6693490 & & & &if (now&_monitorNext) & & & &{ & & & & & &_selects=(int)(_selects*__MONITOR_PERIOD/(now-_monitorStart)); & & & & & &_pausing=_selects&__MAX_SELECTS; & & & & & &if (_pausing) & & & & & & & &_paused++; & & & & & &_selects=0; & & & & & &_jvmBug=0; & & & & & &_monitorStart= & & & & & &_monitorNext=now+__MONITOR_PERIOD; & & & &} & & & &if (now&_log) & & & &{ & & & & & &if (_paused&0) & & & & & & & & &Log.debug(this+& Busy selector - injecting delay &+_paused+& times&); & & & & & &if (_jvmFix2&0) & & & & & & & &Log.debug(this+& JVM BUG(s) - injecting delay&+_jvmFix2+& times&); & & & & & &if (_jvmFix1&0) & & & & & & & &Log.debug(this+& JVM BUG(s) - recreating selector &+_jvmFix1+& times, cancelled keys &+_jvmFix0+& times&); & & & & & &else if(Log.isDebugEnabled() && _jvmFix0&0) & & & & & & & &Log.debug(this+& JVM BUG(s) - cancelled keys &+_jvmFix0+& times&); & & & & & &_paused=0; & & & & & &_jvmFix2=0; & & & & & &_jvmFix1=0; & & & & & &_jvmFix0=0; & & & & & &_log=now+60000; & & & &} & & & &// If we see signature of possible JVM bug, increment count. & & & &if (selected==0 && wait&10 && (now-before)&(wait/2)) & & & &{ & & & & & &// Increment bug count and try a work around & & & & & &_jvmBug++; & & & & & &if (_jvmBug&(__JVMBUG_THRESHHOLD)) & & & & & &{ & & & & & & & &try & & & & & & & &{ & & & & & & & & & &if (_jvmBug==__JVMBUG_THRESHHOLD+1) & & & & & & & & & & & &_jvmFix2++; & & & & & & & & & &Thread.sleep(__BUSY_PAUSE); // pause to avoid busy loop & & & & & & & &} & & & & & & & &catch(InterruptedException e) & & & & & & & &{ & & & & & & & & & &Log.ignore(e); & & & & & & & &} & & & & & &} & & & & & &else if (_jvmBug==__JVMBUG_THRESHHOLD) & & & & & &{ & & & & & & & &synchronized (this) & & & & & & & &{ & & & & & & & & & &// BLOODY SUN BUG !!! &Try refreshing the entire selector. & & & & & & & & & &final Selector new_selector = Selector.open(); & & & & & & & & & &for (SelectionKey k: selector.keys()) & & & & & & & & & &{ & & & & & & & & & & & &if (!k.isValid() || k.interestOps()==0) & & & & & & & & & & & & & & & & & & & & & & & & & &final SelectableChannel channel = k.channel(); & & & & & & & & & & & &final Object attachment = k.attachment(); & & & & & & & & & & & &if (attachment==null) & & & & & & & & & & & & & &addChange(channel); & & & & & & & & & & & &else & & & & & & & & & & & & & &addChange(channel,attachment); & & & & & & & & & &} & & & & & & & & & &_selector.close(); & & & & & & & & & &_selector=new_ & & & & & & & & & & & & & & & & & &} & & & & & &} & & & & & &else if (_jvmBug%32==31) // heuristic attempt to cancel key 31,63,95,... loops & & & & & &{ & & & & & & & &// Cancel keys with 0 interested ops & & & & & & & &int cancelled=0; & & & & & & & &for (SelectionKey k: selector.keys()) & & & & & & & &{ & & & & & & & & & &if (k.isValid()&&k.interestOps()==0) & & & & & & & & & &{ & & & & & & & & & & & &k.cancel(); & & & & & & & & & & & &cancelled++; & & & & & & & & & &} & & & & & & & &} & & & & & & & &if (cancelled&0) & & & & & & & & & &_jvmFix0++; & & & & & & & & & & & & & &} & & & &} & & & &else if (__BUSY_KEY&0 && selected==1 && _selects&__MAX_SELECTS) & & & &{ & & & & & &// Look for busy key & & & & & &SelectionKey busy = selector.selectedKeys().iterator().next(); & & & & & &if (busy==_busyKey) & & & & & &{ & & & & & & & &if (++_busyKeyCount&__BUSY_KEY && !(busy.channel() instanceof ServerSocketChannel)) & & & & & & & &{ & & & & & & & & & &final SelectChannelEndPoint endpoint = (SelectChannelEndPoint)busy.attachment(); & & & & & & & & & &Log.warn(&Busy Key &+busy.channel()+& &+endpoint); & & & & & & & & & &busy.cancel(); & & & & & & & & & &if (endpoint!=null) & & & & & & & & & &{ & & & & & & & & & & & &dispatch(new Runnable() & & & & & & & & & & & &{ & & & & & & & & & & & & & &public void run() & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & &try & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & &endpoint.close(); & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & & & &catch (IOException e) & & & & & & & & & & & & & & & &{ & & & & & & & & & & & & & & & & & &Log.ignore(e); & & & & & & & & & & & & & & & &} & & & & & & & & & & & & & &} & & & & & & & & & & & &}); & & & & & & & & & &} & & & & & & & &} & & & & & &} & & & & & &else & & & & & & & &_busyKeyCount=0; & & & & & &_busyKey= & & & &} & &} & & & &在checkjvmbugs的方法中,当主线程正在阻塞selector.select(wait)时,子线程出现blockwrite的情况,会导致主线程被惊醒,使得主线程select到的事件数为0,当selector管理大量的连接时,会出现1秒内上百次主线程被惊醒,最终在checkjvmbugs方法内被当作是jvmbug来处理了,强制让主线程休眠50毫秒,而此时还有大量的线程注册阻塞事件,并等待主线程的唤醒。最终一个12K的数据花费了50ms的时间来写往客户端,最终导致性能下降。 & &问题已经很清晰,jetty自身的阻塞-唤醒机制被当作jvmbugs来处理,导致数据传输性能受影响,这样的情况也只有在有大量连接和数据传输的时候才会体现出来。 & &修改方案,可以将checkjvmbugs调用直接注释掉,保留每秒select 25000次后休眠一段时间的实现即可。也可以将50毫秒的休眠时间调短来避免阻塞时间过长的问题。 & &分析最新的jetty代码,发现这个checkjvmbugs的调用已经去掉了,正是按照方案1来实现的。 & &问题明确了之后,看似比较简单,但实际上发现问题的过程是很漫长和曲折的,在问题已经锁定在上面之后,有幸参与最终的定位并且分析出了具体的问题点,问题找到的那一刻,有一种兴奋感与成就感。
觉得文章有用?立即:
和朋友一起 共学习 共进步!
建议继续学习:
QQ技术交流群:,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
作者:&&&&来源:
发布时间: 23:06:25
努力让您和作者直接沟通
建议继续学习
近3天十大热文
rightLowest
& 2009 - 2015 本页面所有内容,转载请注明出处 站长@2120人阅读
有个服务器,既有数据库服务器,又有网络服务器,还有很多定时运行的程序。网络服务器闲时一个星期出现两三次SQL Server timed out 问题,忙时每天出现四五次SQL Server timed out问题,有时还经常出现互锁冲突。小老板不高兴,是程序员出身,但是是那种水平一般般的那种,总觉得是哪个SQL 语句性能太差,把SQL server搞垮了。搞了两年的SQL语句优化问题,还是没有解决,真的是很烦,我老觉得不应该是SQL语句性能的问题,因为找了这么多年,烂SQL应该都没了。应该是web 服务器或者其他原因导致了机器过载,然后导致数据库服务器性能下降,导致SQL
Server timed out问题。但是又找不到直接导致的原因,又不想天天去优化那些不该优化的SQL。就这事经常和小老板经常有冲突。
老板把服务器内存加大到32G,问题还是出现。
最近发现有个定时运行的程序产生的日志没有出现,这个程序有好几个copy(每个copy有不同的运行参数)每分钟运行一次,不管成功不成功都要生成一些日志。这非常蹊跷,为什么没有日志呢?
怀疑程序可能根本没有运行,所以日志没有出现。
这个程序由windows 2008服务器的scheduler每分钟定时运行,查看scheduler的日志,发现日志无法查看,新产生的日志马上就消失,原因是太多的日志产生了所以一秒钟前的日志因为后一秒产生的日志太多而被删掉了。再看scheduler的设置,发现是“失败立即重新运行”和“如果有同样的程序运行就放弃”。
原因出来了,由于网络服务器很忙时,定时运行的程序由于要处理的东西非常多运行时间比较长,要20分钟才能完成,结果因为同样程序在运行即使轮到它也不能运行。但是失败了马上又重新运行,这样一个周期在一秒钟内估计反复几千次,把CPU资源耗尽了,所以导致无法启动定时程序,所以也没有日志产生。同样因为CPU资源耗尽,导致数据库服务器反应很慢,导致timed out和互锁冲突。
把scheduler设置改了改,如果失败每隔一分钟尝试一次但是最多运行3次。
SQL Server timed out和互锁冲突再也没有出现过。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:63587次
积分:1111
积分:1111
排名:第19923名
原创:47篇
评论:24条
(1)(1)(1)(1)(2)(3)(1)(3)(1)(2)(1)(1)(2)(2)(2)(2)(1)(9)(11)(1)(1)1. 多线程编程时,有时候需要统计某个变量或对象的创建个数或者是根据某个变量值来判断是否需要继续执行下去,这时候互锁函数是比较高效的方案之一了。
1.原子访问:(互锁函数族)
-- 原子访问,指线程在访问资源时能够确保所有其他线程都不在同一时间内访问相同的资源.
-- 调用一个互锁函数通常只需要执行几个CPU周期(通常小于50),并且不需要从用户模式转换为内核模式(通常这需要1000个CPU周期).
-- 互锁函数是CPU硬件支持的,如果是x86处理器,互锁函数会向总线发出一个硬件信号,防止其他处理器访问同一个内存地址.
-- 无论编译器怎么生成代码,无论计算机中安装了多少个处理器,都能那个保证以原子操作方式来修改一个值.
-- 必须保证传递给这个函数的变量地址正确的对齐,否则这些函数就会运行失败.
(1) CPU处理准确对齐的数据时,它的运行效率最高.在用数据的大小对内存地址取模,结果为0时,数据是对齐的。例如,WORD类型的值
& & 应该总是从能够被2除尽的地址开始,而DWORD类型的值则应该总是从能够被4除尽的地址开始.
test_interlock.cpp
// test_interlock.cpp : 定义控制台应用程序的入口点。
// 原子访问: 互锁的函数家族.
#include &stdafx.h&
#include &Windows.h&
#include &stdint.h&
#include &assert.h&
#include &iostream&
static int32_t gCount = 0;
static int32_t gExecuteCount = 0;
static const int kThreadNum = 10;
static const int kLoopNum = 1000;
static uint32_t setted = 0;
#define APR_ALIGN(size, boundary) \
(((size) + ((boundary) - 1)) & ~((boundary) - 1))
DWORD WINAPI ThreadFunc(PVOID pvParam)
long* g_x = (long*)pvP
for(int i = 0; i& kLoopN ++i)
//cout && &sync_func CurrentThreadID: & && GetCurrentThreadId() &&
InterlockedExchangeAdd(g_x,1);
InterlockedExchange(&setted,i%2);
//1.让其他线程也有机会执行.
Sleep(10);
void TestInterlockedExchangeAdd()
HANDLE hThreads[kThreadNum];
//《Windows核心编程》说地址要对齐,虽然x86会额外做对齐的指令操作.
// 但是能自己对齐还是自己对齐吧.比如AMD cpu不对齐可能会出现问题.
long g_x = 0;
for(int i = 0; i& kThreadN ++i)
DWORD dwThreadID;
hThreads[i] = CreateThread(NULL,0,ThreadFunc,&g_x,0,&dwThreadID);
DWORD rc = WaitForMultipleObjects(kThreadNum, hThreads, TRUE, INFINITE);
assert(rc == WAIT_OBJECT_0);
for(int i = 0; i& kThreadN ++i)
CloseHandle(hThreads[i]);
assert(g_x == 10000);
assert(setted == 1);
int _tmain(int argc, _TCHAR* argv[])
TestInterlockedExchangeAdd();
《Windows核心编程》
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:200253次
积分:3957
积分:3957
排名:第3561名
原创:180篇
转载:12篇
评论:58条
公司急需2015有上进心的,聪明的C++开发有经验者(人才),优先考虑有个人作品的实干派. 有兴趣的加QQ:
联系,注明qixingshi. 公司网站:
阅读:3412
文章:29篇
阅读:23117
文章:23篇
阅读:23332
(8)(5)(5)(5)(7)(4)(9)(10)(4)(5)(5)(5)(6)(7)(8)(8)(7)(5)(7)(6)(6)(7)(2)(4)(4)(4)(4)(5)(4)(5)(8)(16)如图为三项电动机正反车,我就想问下图中的互锁是不是在旁边加了两个常闭按钮啊?还是怎么接法_百度知道
如图为三项电动机正反车,我就想问下图中的互锁是不是在旁边加了两个常闭按钮啊?还是怎么接法
com/zhidao/wh%3D600%2C800/sign=60f3bc1c58b5c9ea62a60be5e1a18b87d6277fca47b82f2b381f30e924fc54://e.com/zhidao/pic/item/d6277fca47b82f2b381f30e924fc54.hiphotos.hiphotos.hiphotos.baidu.jpg" esrc="http.jpg" target="_blank" title="点击查看大图" class="ikqb_img_alink"><img class="ikqb_img" src="http://e://e./zhidao/wh%3D450%2C600/sign=62bb6a1eb5003af34defd464001aea6a/d6277fca47b82f2b381f30e924fc54&<a href="http
就是把两个接触器的线圈都要通过另一个接触器的常闭触点来串接,一个接触器吸合,另一个就会再吸合了,也就是只能正转或反转
那图中上边第一个话问好的位置也就是km2的常闭触点?
那中间的虚线连锁是怎么讲啊?
带问?号的是常闭触点,中间的虚线连锁是表示:如果KM1接触器工作,KM1的常闭触点就断开了,KM2接触器的线圈因为是和KM1的常闭触点串连,所以不能形成回路,就不能吸合工作了,反之一样。
其他类似问题
为您推荐:
其他2条回答
这类接触器都带常闭和常开的,付助触点
它的接法是互锁的
用自己的常闭去锁别人的常开就可以了!
你是指接触器常闭触点短接常开按钮
用一号接触器的常闭去控制二号接触器的常开
你的意思还就是说sb1km1去连接km2的常闭触点
然后km2下口给线圈
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 机械互锁 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信