精华内容
下载资源
问答
  • 您可以改为使用条件变量,并选择单调时钟作为参考时钟.... 但情况比这更糟糕……系统时钟可能会在你调用clock_gettime()之后调用sem_timedwait()之前进行调整……所以就你所知,你希望sem_timedwait()等待两天.

    您可以改为使用条件变量,并选择单调时钟作为参考时钟.信号量有点老,我会避免在新的应用程序中使用它们.如果您愿意,可以使用条件变量和互斥量轻松实现信号量.

    pthread_condattr_t cattr;

    pthread_condattr_init(&cattr);

    pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC);

    pthread_cond_t cond;

    pthread_cond_init(&cond, &cattr);

    struct timespec ts;

    clock_gettime(CLOCK_MONOTONIC, &ts);

    ts.tv_nsec += 100000000;

    if (ts.tv_nsec >= 1000000000) {

    ts.tv_nsec -= 1000000000;

    ts.tv_sec += 1;

    }

    int r = pthread_cond_timedwait(&cond, &mutex, &ts);

    if (r == ETIMEDOUT) {

    // ...

    } else {

    // ...

    }

    单调时钟“不受系统时间内不连续跳跃的影响”(man clock_gettime),因此它正是您对此类应用所需要的.

    你说,

    Now it happens that the system time gets set by an external process (ntp) while waiting for the semaphore.

    但情况比这更糟糕……系统时钟可能会在你调用clock_gettime()之后调用sem_timedwait()之前进行调整……所以就你所知,你希望sem_timedwait()等待两天.

    展开全文
  • time_wait和close_wait(面试被问到)

    千次阅读 2013-07-10 21:42:57
    总结: 一端忘记close,将造成另一端大量的close_wait的状态。...TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的

    总结:

    一端忘记close,将造成另一端大量的close_wait的状态。

    主动执行close的一端,在量特别大的情况下,对so_linger没有做设置,将造成大量的time_wait状态的连接。



    TCP状态转移要点
    TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不会被释放。网络服务器程序要同时管理大量连接,所以很有必要保证无用连接完全断开,否则大量僵死的连接会浪费许多服务器资源

    客户端TCP状态迁移:
    CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
    服务器TCP状态迁移:
    CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
    当客户端开始连接时,服务器还处于LISTENING,客户端发一个SYN包后,他就处于SYN_SENT状态,服务器就处于SYS收到状态,然后互相确认进入连接状态ESTABLISHED.

     

    1、LISTENING状态
     服务启动后首先处于侦听(LISTENING)状态。

    2、ESTABLISHED状态
     ESTABLISHED的意思是建立连接。表示两台机器正在通信。

    3、CLOSE_WAIT

    对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭

    4、TIME_WAIT

    我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT,缺省为240秒。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。处于TIME_WAIT状态的连接占用的资源不会被内核释放,所以作为服务器,在可能的情况下,尽量不要主动断开连接,以减少TIME_WAIT状态造成的资源浪费。

    目前有一种避免TIME_WAIT资源浪费的方法,就是关闭socket的LINGER选项。但这种做法是TCP协议不推荐使用的,在某些情况下这个操作可能会带来错误

     

    断开连接的时候, 当发起主动关闭的左边这方发送一个FIN过去后,右边被动关闭的这方要回应一个ACK,这个ACK是TCP回应的,而不是应用程序发送的,此时,被动关闭的一方就处于CLOSE_WAIT状态了。如果此时被动关闭的这一方不再继续调用closesocket,那么他就不会发送接下来的FIN,导致自己老是处于CLOSE_WAIT。只有被动关闭的这一方调用了closesocket,才会发送一个FIN给主动关闭的这一 方,同时也使得自己的状态变迁为LAST_ACK。

    出现大量CLOSE_WAIT的原因很简单,就是某一方在网络连接断开后,没有检测到这个错误,没有执行closesocket,导致了这个状态的实现,这在TCP/IP协议的状态变迁图上可以清楚看到。同时和这个相对应的还有一种叫TIME_WAIT的。一端的Socket调用close后,另一端的Socket没有调用close

    另外,把SOCKET的SO_LINGER设置为0秒拖延(也就是立即关闭)在很多时候是有害处的。 
    还有,把端口设置为可复用是一种不安全的网络编程方法

    当主动关闭的一方发送FIN到被动关闭这边后,被动关闭这边的TCP马上回应一个ACK过去,同时向上面应用程序提交一个ERROR,导 致上面的SOCKET的send或者recv返回SOCKET_ERROR,正常情况下,如果上面在返回SOCKET_ERROR后调用了closesocket,那么被动关闭的者一方的TCP就会发送一个FIN过去,自己的状态就变迁到LAST_ACK

    image

    虚线和实线分别对应服务器端(被连接端)和客户端端(主动连接端)。

    结合上图使用netstat -na命令即可知道到当前的TCP连接状态。一般LISTEN、ESTABLISHED、TIME_WAIT是比较常见。

    分析:

    这个问题主要因为TCP的结束流程未走完,造成连接未释放。现设客户端主动断开连接,流程如下

    Client 消息 Server

    close()
    ------ FIN ------->
    FIN_WAIT1 CLOSE_WAIT
    <----- ACK -------
    FIN_WAIT2 
    close()
    <------ FIN ------ 
    TIME_WAIT LAST_ACK

    ------ ACK -------> 
    CLOSED
    CLOSED

    如上图所示,由于Server的Socket在客户端已经关闭时而没有调用关闭,造成服务器端的连接处在“挂起”状态,而客户端则处在等待应答的状态上。此问题的典型特征是:一端处于FIN_WAIT2 ,而另一端处于CLOSE_WAIT

    于基于TCP的HTTP协议,关闭TCP连接的是Server端,这样,Server端会进入TIME_WAIT状态,可 想而知,对于访问量大的Web Server,会存在大量的TIME_WAIT状态,假如server一秒钟接收1000个请求,那么就会积压240*1000=240,000个TIME_WAIT的记录,维护这些状态给Server带来负担。当然现代操作系统都会用快速的查找算法来管理这些TIME_WAIT,所以对于新的TCP连接请求,判断是否hit中一个TIME_WAIT不会太费时间,但是有这么多状态要维护总是不好。



    下面列举网络连接中用netstat -na查看某些状态的意思:


    以上这些可以加深我们对TCP通信的理解

    ======================

    linux下time_wait过多解决记录

    问题起因:

    自己开发了一个服务器和客户端,通过短连接的方式来进行通讯,由于过于频繁的创建连接,导致系统连接数量被占用,不能及时释放。看了一下18888,当时吓到了。


    现象:

    1、外部机器不能正常连接SSH

    2、内向外不能够正常的ping通过,域名也不能正常解析。


    问题排查:

    通过 netstat  -anp | grep TIME_WAIT | wc -l 命令查看数量,发现TIME_WAIT的连接数量超过了18000太夸张了。

    1、初步怀疑是程序没有关闭连接,codereview了两遍,发现,已经正常关闭。

    2、网上看TIME_WAIT产生的原因,可能是因为服务器主动关闭连接导致TIME_WAIT产生。

    3、查找TIME_WAIT解决方案:

    发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,
    vi /etc/sysctl.conf

    编辑文件,加入以下内容:
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 30

    然后执行 /sbin/sysctl -p 让参数生效。


    经过配置后,暂时的问题是解决了,再查看TIME_WAIT数量快速下降。


    关键命令:

    1、netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'

    会得到类似下面的结果,具体数字会有所不同:

    LAST_ACK 1
    SYN_RECV 14
    ESTABLISHED 79
    FIN_WAIT1 28
    FIN_WAIT2 3
    CLOSING 5
    TIME_WAIT 1669

    状态:描述
    CLOSED:无连接是活动的或正在进行
    LISTEN:服务器在等待进入呼叫
    SYN_RECV:一个连接请求已经到达,等待确认
    SYN_SENT:应用已经开始,打开一个连接
    ESTABLISHED:正常数据传输状态
    FIN_WAIT1:应用说它已经完成
    FIN_WAIT2:另一边已同意释放
    ITMED_WAIT:等待所有分组死掉
    CLOSING:两边同时尝试关闭
    TIME_WAIT:另一边已初始化一个释放
    LAST_ACK:等待所有分组死掉


    2、sysctl -a | grep time | grep wait
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120




    展开全文
  • 如果忽略某些错误,让其它操作继续进行是有意义的的话,waitGroup可能是个更好的选择 package main import ( "context" "fmt" "net/http" "os" "os/signal" "sync" "syscall" "time" log "github....

    errGroup默认情况下应在第一个错误发生时取消所有未完成的操作,但是这不见得是我们所需要的。如果忽略某些错误,让其它操作继续进行是有意义的的话,waitGroup可能是个更好的选择

    package main
    
    import (
    	"context"
    	"fmt"
    	"net/http"
    	"os"
    	"os/signal"
    	"sync"
    	"syscall"
    	"time"
    
    	log "github.com/sirupsen/logrus"
    )
    
    func main() {
    	log.SetLevel(log.TraceLevel)
    
    	wg := &sync.WaitGroup{}
    
    	srv := http.Server{
    		Addr:         ":45678",
    		WriteTimeout: time.Second * 15,
    		ReadTimeout:  time.Second * 15,
    		IdleTimeout:  time.Second * 60,
    	}
    
    	http.Handle("/", Adapt(http.HandlerFunc(worker),
    	                       WithWaitGrp(wg),
    	                       Log()))
    
    	go StartServer(&srv)
    	WaitForShutdown(wg, &srv)
    }
    
    func WaitForShutdown(wg *sync.WaitGroup, srv *http.Server) {
    	wg.Add(1)
    	go waitForShutdown(wg, srv)
    	wg.Wait()
    }
    
    func waitForShutdown(wg *sync.WaitGroup, srv *http.Server) {
    	defer wg.Done()
    
    	termChan := make(chan os.Signal)
    	signal.Notify(termChan, syscall.SIGTERM, syscall.SIGINT)
    
    	sig := <-termChan
    	log.Infof("signal %+v received. Shutdown sequence commenced", sig)
    	//  停止监听端口,关掉空闲连接,并无限等待未完成连接
    	if err := srv.Shutdown(context.Background()); err != nil {
    		log.Errorf("shutdown error %+v", err)
    	}
    }
    
    func StartServer(srv *http.Server) {
    	if err := srv.ListenAndServe(); err != nil {
    		if err == http.ErrServerClosed {
    			log.Trace("server closed")
    		} else {
    			log.Errorf("listen and serve error %+v", err)
    		}
    	}
    }
    
    func worker(w http.ResponseWriter, r *http.Request) {
    	if r.URL.Path != "/" {
    		http.NotFound(w, r)
    		return
    	}
    	time.Sleep(5 * time.Second) // 耗时5秒的请求
    	_, _ = fmt.Fprint(w, "ok")
    }
    
    type Adapter func(http.Handler) http.Handler
    
    func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
    	for _, adapter := range adapters {
    		h = adapter(h)
    	}
    	return h
    }
    
    type StatusRecorder struct {
    	http.ResponseWriter
    	Status int
    }
    
    func (r *StatusRecorder) WriteHeader(status int) {
    	r.Status = status
    	r.ResponseWriter.WriteHeader(status)
    }
    
    func Log() Adapter {
    	return func(h http.Handler) http.Handler {
    		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    			recorder := &StatusRecorder{
    				ResponseWriter: w,
    				Status:         200,
    			}
    			start := time.Now()
    			h.ServeHTTP(recorder, r)
    			log.Infof("%s %d %s %dns %+[4]v", r.URL.Path, recorder.Status, r.RemoteAddr, time.Since(start))
    		})
    	}
    }
    
    func WithWaitGrp(wg *sync.WaitGroup) Adapter {
    	return func(h http.Handler) http.Handler {
    		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    			wg.Add(1)
    			defer wg.Done()
    			h.ServeHTTP(w, r)
    		})
    	}
    }
    
    展开全文
  • 当使用subprocess.Popen()从我的python脚本中生成同一应用程序的几个实例,我遇到一些问题,使用线程...我仅使用一个线程进行实验,并在进程开始打印文本消息,以及完成.所以线程函数看起来像这样:def worker():...

    当使用subprocess.Popen()从我的

    python脚本中生成同一应用程序的几个实例时,我遇到一些问题,使用线程让它们同时运行.在每个线程中,我使用popen()调用运行应用程序,然后等待它通过调用wait()来完成.问题似乎是wait() – 调用实际上并不等待进程完成.我仅使用一个线程进行实验,并在进程开始时打印文本消息,以及完成时.所以线程函数看起来像这样:

    def worker():

    while True:

    job = q.get() # q is a global Queue of jobs

    print('Starting process %d' % job['id'])

    proc = subprocess.Popen(job['cmd'], shell=True)

    proc.wait()

    print('Finished process %d' % job['id'])

    job.task_done()

    但即使我只使用一个线程,它会打印出几个“启动进程…”消息,然后任何“完成进程…”消息出现.有没有wait()实际上不等待的情况?我有几个不同的外部应用程序(C控制台应用程序),反过来将有几个实例同时运行,其中一些我的代码工作,但对于其他的它不会.外部应用程序可能会有某些问题影响到wait()的调用?

    用于创建线程的代码如下所示:

    for i in range(1):

    t = Thread(target=worker)

    t.daemon = True

    t.start()

    q.join() # Wait for the queue to empty

    更新1:

    我还应该补充说,对于某些外部应用程序,我有时会得到一个-1073471801的返回码(proc.returncode).例如,其中一个外部应用程序会给Popen被调用的前两次的返回码,而不是最后两个(当我有四个作业时).

    更新2:

    为了清理起来,现在我在队列中有四个工作,这四个不同的测试用例.当我运行代码时,对于其中一个外部应用程序,前两个Popen调用生成返回代码-1073471801.但是,如果我打印了Popen调用的确切命令,并在命令窗口中运行它,它将执行没有任何问题.

    解决了!

    我设法解决了我遇到的问题.我认为问题是我缺乏线程编程经验.我错过了一个事实,当我创建了我的第一个工作线程,他们将继续生活,直到python脚本退出.我错误地创建了更多的工作线程,每次我把新的项目放在队列(我为每个外部程序我想运行批量进行).所以当我得到第四个外部应用程序时,我有四个线程同时运行,尽管我只是以为我有一个.

    展开全文
  • TIME_WAIT 为主动关闭的那端最后经历的状态,持续时间为2MSL。 MSL 是 Maxmum Segment Lifetime 报文最大生存时间。一般根据实际的网络情况进行确定。 为什么要持续这么长的时间? 原因一:可靠地实现 TCP 全双工...
  • wait函数

    2019-06-06 08:52:59
    一个进程在终止会关闭所有文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,内核在其中包含了一些信息。如果正常终止则保存着推出状态,如果是...进行查看,因为Shell是它的父进程,终止Shell调用w...
  • sync 包的 WaitGroup 类型主 goroutine 等待其他手动启动的 goroutine 可以考虑 sync.WaitGroup 类型,它比通道更适合实现这种一对多的 goroutine 协作流程。sync.WaitGroup 是开箱即用的,也是并发安全的。同时,...
  • wait方法

    千次阅读 2019-03-24 10:33:14
    Java中的多线程是一种抢占式的机制而不是分机制。线程主要有以下几种状态:可运行,运行,阻塞,等待,等待超时,死亡。抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行。 当有多个线程访问...
  • sleep与wait区别:1、sleep方法是...wait方法是在获取锁情况下进行等待的,等待会释放锁;3、都可以响应中断。public class Test {static Object lock = new Object();public static void main(String[] args) {//...
  • wait( ),notify( ),notifyAll( )都不属于Thread类,而是属于Object基础类,...当需要调用以上的方法的时候,一定要对竞争资源进行加锁,如果不加锁的话,则会报 IllegalMonitorStateException 异常 当想要调用wait...
  • UPDATE FOR WAIT 和 UPDATE FOR NOWAIT

    千次阅读 2009-03-10 13:53:00
    当你准备对一条数据进行更新,为了防止他端的更新操作,可能需要对表进行锁定出力。经常用的一条语句就是:SELECT ... FROM TABLE WHERE ... UPDATE FOR NOWAIT其中,NOWAIT可以用WAIT来替换。NOWAIT的作用是别人...
  • wait和sleep

    2020-05-02 10:40:36
    wait()是属于Object类中的,会释放对象锁,只有当其他线程调用notify()才可以唤醒本线程,wait()使用,必须先获取对象锁,也就是必须在synchronized修饰的代码块中进行使用,notify()同,如果没有在synchronized...
  • /** * 曾经的面试题:(淘宝?... * 写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个,线程2给出提示并结束 * * 给lists添加volatile之后,t2能够接到通知,但是,t2线程的死循...
  • wait和sleep区别

    2021-04-01 10:58:10
    1 sleep和wait区别 从表面上看,wait和sleep...wait方法的执行必须在同步方法中进行,而sleep则不需要。 线程在同步方法中执行sleep方法,并不会释放monitor的锁,而wait方法则会释放monitor的锁,并且将线程添加到该
  • java notify 和 wait

    2020-07-26 11:04:39
    notify 和 wait wait()方法是从运行态回阻塞态。...wait()方法只能在同步方法或同步代码块中调用,如果调用wait()没有适当的锁,会抛出异常。 wait()方法执行后,当前线程释放锁,其他线程可以
  • ORACLE操作表”资源正忙,需指定nowait"的解锁方法 问题: 执行 drop table table_name ,提示”资源正忙,需指定nowait"由于TB_PROJECT为设置主键造成只能...表示table_name表由某个用户操作时进行了锁定,必...
  • wait & notify

    2021-03-22 15:38:54
    线程同步:当有一个线程在对内存进行操作,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作,而其他线程又处于等待状态,实现线程同步的方法有很多,临界区对象...
  • TIME_WAIT

    2019-12-19 20:00:26
    TCP连接终止,主机1先发送FIN报文,主机2进入COLSE_WAIT状态,并发送一个ACK应答,同时,主机2通过read调用获得EOF,并将此结果通知应用程序进行主动关闭操作,发送FIN报文。主机1在接收到FIN报文后发送ACK应答,...
  • python中使用socket进行编程,发现client的tcp经常处于close_wait状态:linux中使用命令 # netstat -atpn原因是server端关掉了tcp连接,给client发送FIN信号,client的tcp层回了ACK,然后它的socket状态就处于...
  • TIME_WAIT状态

    2020-09-10 18:27:13
    TCP 连接终止,主机 1 先发送 FIN 报文,主机 2 进入 CLOSE_WAIT 状态,并发送一个 ACK 应答,同时,主机 2 通过 read 调用获得 EOF,并将此结果通知应用程序进行主动关闭操作,发送 FIN 报文。主机 1 在接收到 ...
  • 等待/通知机制在生活中比比皆是,比如在就餐就会出现 厨师和服务员之间的交互要在“菜品传递台”上,在这期间会有几个问题: 1)厨师做完一道菜的时间不确定,所以厨师将菜品放到“菜品传递台”上的时间也是不确定...
  • 线上大量CLOSE_WAIT分析

    2018-12-13 09:35:31
    这一次重启真的无法解决问题了:一次 MySQL 主动关闭,导致服务出现大量 CLOSE_WAIT 的全流程排查过程。 近日遇到一个线上服务 socket 资源被不断打满的情况。通过各种工具分析线上问题,定位到问题代码。这里对该...
  • iowait

    千次阅读 2013-02-22 11:36:02
    后面实在不行就对物理机进行重启,启动进不去系统,准备重装发现硬盘灯有黄灯。由于有raid,把坏硬盘拔掉,就工作正常了。 中间定位iowait的过程涉及命令有: # iostat -x 1 Linux 2.6.32-220.el6.x86_64 ...
  • 当你准备对一条数据进行更新,为了防止他端的更新操作,可能需要对表进行锁定出力。经常用的一条语句就是:SELECT ... FROM TABLE WHERE ... UPDATE FOR NOWAIT其中,NOWAIT可以用WAIT来替换。NOWAIT的作用是别人...
  • java多线程wait方法

    2019-12-06 22:21:40
    方法wait()的作用是使当前执行代码的线程进行等待,wait()方法是Object类的方法,该方法是用来将当前线程 置入“预执行队列”中,并且在wait()所在的代码处停止执行,直到接到通知或被中断为止。 wait()方法只能在...
  • 这一次重启真的无法解决问题了:一次 MySQL 主动关闭,导致服务出现大量 CLOSE_WAIT 的全流程排查过程。近日遇到一个线上服务 socket 资源被不断打满的情况。通过各种工具分析线上问题,定位到问题代码。这里对该问题...
  • 这一次重启真的无法解决问题了:一次 MySQL 主动关闭,导致服务出现大量 CLOSE_WAIT 的全流程排查过程。近日遇到一个线上服务 socket 资源被不断打满的情况。通过各种工具分析线上问题,定位到问题代码。这里对该问题...
  • 慢查询日志,将那些执行时间过长且占用资源过多的SQL拿来进行explain分析,导致CPU过高,多数是GroupBy、OrderBy排序问题所导致,然后慢慢进行优化改进。比如优化insert语句、优化group by语句、优化order by语句、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,065
精华内容 826
关键字:

wait进行时