记一次C程序线程大面积假死、卡住

今天是客户要求的最后期限,可突然发现一种操作方式下,程序会很容出现线程大面积卡住。

程序开了数十个线程,每个都会ping一个ip。

于是有人说是线程太多,有人说是发包太多,还有说是usleep会导致卡死。

gdb连接上卡死的程序:

gdb main pid

info threads
发现确实很多程序处于usleep。

网上很多说用select的,同事给了一段用select的,结果最基本的sleep时间都远远不对(估计是什么低级错误)。我也不喜欢select,因为效率低。

后来换了naosleep,

void sleepSelect1(unsigned int us, char* file, int line)
{
	struct timespec ts1;
	struct timespec ts = {
			us / 1000000,
			(us % 1000000) * 1000
	};

	while ((-1 == nanosleep(&ts, ts1)) && (EINTR == errno));
}

结果还是会全面卡住,而且似乎更快,

后来换pthread_cond_timedwait:

void sleepSelect2(unsigned int us, char* file, int line)
{
	pthread_mutex_t *mutex = malloc(sizeof(pthread_mutex_t));
	pthread_cond_t *cond = malloc(sizeof(pthread_cond_t));

	memset(mutex, 0, sizeof(pthread_mutex_t));
	memset(cond, 0, sizeof(pthread_cond_t));

	struct timespec *deadline=malloc(sizeof(struct timespec));
	struct timeval *now=malloc(sizeof(struct timeval));

	gettimeofday(now,NULL);
	long nanoseconds = (us % 1000000) * 1000;

	deadline->tv_sec = now->tv_sec + seconds;
	deadline->tv_nsec = now->tv_usec * 1000 + nanoseconds;

	if( deadline->tv_nsec >= 1000000000L )
	{
		deadline->tv_nsec -= 1000000000L;
		deadline->tv_sec++;
	}

	pthread_mutex_lock(mutex);
	pthread_cond_timedwait(cond,mutex,deadline);
	pthread_mutex_unlock(mutex);

	free(deadline);
	free(now);
	free(mutex);
	free(cond);
}

同样会大面积卡住在 pthread_cond_timedwait。而且发现把sleep(50)这样专用 cond_timedwait会直接卡住。

后来我发现sleep最终也是nanosleep实现的,nanosleep要传2个参数,我却没有搜索到第二个参数的意义。这让我想起另外一个函数gettimeofday的第二参数,我都是传的null。。。。

下面这段代码,用上之后:程序没有卡住了:

void sleepSelect1(unsigned int us, char* file, int line)
{
	struct timespec ts = {
			us / 1000000,
			(us % 1000000) * 1000
	};

	while ((-1 == nanosleep(&ts, NULL)) && (EINTR == errno));
}

#define sleepSelect(us) sleepSelect1(us, __FILE__, __LINE__)

sleepSelect就等同于 usleep

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值