Linux多线程编程,替代sleep的几种方式

上一篇 / 下一篇  2012-08-30 13:17:07 / 个人分类:Linux

51Testing软件测试网jRB| y

  我只想要进程的某个线程休眠一段时间的,可是用sleep()是将整个进程都休眠的,这个可能就达不到,我们想要的效果了。目前我知道有三种方式:

;T$b4dLs\'N-l051Testing软件测试网HPgSQ7|J

  1、usleep

l$fZ^(p0

OjYK t-M0  这个是轻量级的,听说能可一实现线程休眠,我个人并不喜欢这种方式,所以我没有验证它的可行信(个人不推荐)。51Testing软件测试网6e%J+^^H%Uqe;py

51Testing软件测试网#J5W5Hu2N}0W

  2、select

K+akX+MR;^:J?H0

v+Ef U^1m2?0  这个可以,我也用过这种方式,它是在轮询。

ma#Z6J P-AnH051Testing软件测试网NE/uG r

  3、pthread_cond_timedwait

?"hn^;InV0

2S7M!S.zIB0   采用pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t *mutex, const struct timespec *abstime)可以优雅的解决该问题,设置等待条件变量cond,如果超时,则返回;如果等待到条件变量cond,也返回。本文暂不将内部机理,仅演 示一个demo。51Testing软件测试网 i k6h0Z-G[g s/` W.mi

51Testing软件测试网*B&G;yvqM

  首先,看这段代码,thr_fn为一个线程函数:51Testing软件测试网 P6y,~.fH.eU eQ4H%@

51Testing软件测试网9|Q\|+J \

#include <stdio.h>
[o$S3]7~ g G4eF0#include <stdlib.h>

kri H3@+h!@051Testing软件测试网+O;R9h5`-tuo.v

int flag = 1;51Testing软件测试网_#W WK A"K8Pr
void * thr_fn(void * arg) {
\VU/~N\ ~)R0  while (flag){
5uR/?5i#~0    printf("******\n");51Testing软件测试网5iA!CSFk8P&c P
    sleep(10);51Testing软件测试网3gL+bB7W0i)d1m G t
  }
"D.z-\ I*HKU'Q n;r9w0  printf("sleeptestthread exit\n");
;?*e_cs0}51Testing软件测试网 g&a4c*V,x6AM9?{
 51Testing软件测试网9f'C'l J,D$u
int main() {51Testing软件测试网"b F x6\ Z'yA1|P `
  pthread_t thread;
?#g3p)S0I6u0  if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) {51Testing软件测试网r^.}.[)^
    printf("error when create pthread,%d\n", errno);51Testing软件测试网\6{\;VJ VVzM
    return 1;51Testing软件测试网&]5\&o+VbMQI
  }
u[ Vo)pE)TF0 51Testing软件测试网#xb$P_*KaK a
  char c ;
gtNKf8b"A0  while ((c = getchar()) != 'q');
rK-G/F Mv b;YE3q/S0 
&NqR Hj5u/Q0  printf("Now terminate the thread!\n");51Testing软件测试网J2S4Lr5C}F#mO
  flag = 0;51Testing软件测试网V)N s+x$nG kb"]P
  printf("Wait for thread to exit\n");51Testing软件测试网P(m/N_k]b"e
  pthread_join(thread, NULL);51Testing软件测试网'M*VxJ2y2w
  printf("Bye\n");51Testing软件测试网b.A b,P E&C
  return 0;
0G'rR:u8MO0}

:@&Zdr0bji1z0

1q:C-m.MFb0  输入q后,需要等线程从sleep中醒来(由挂起状态变为运行状态),即最坏情况要等10s,线程才会被join。采用sleep的缺点:不能及时唤醒线程。

AL0b9PUH0

mB(Lo4w0  采用pthread_cond_timedwait函数实现的如下:

e,xj1Fe\ h0

M8I.jWc;Y/J \1].E3pR%D051Testing软件测试网d u:eGBxA3};Nua

51Testing软件测试网9s7LM Ss8HL

#include <stdio.h>51Testing软件测试网;B y#g H#{ r8]]5@\ W
#include <sys/time.h>
Bs?a:h [ \Ao0#include <unistd.h>
Z0@3N uY C3w;l[v7t0#include <pthread.h>
D6Wu1X5t'x8|%J!_0#include <errno.h>
!v2e'^S0nQ|.w0 51Testing软件测试网c3IwM(ei%?[~
static pthread_t thread;
td+q6L-r8Q0static pthread_cond_t cond;
qa|3gW`0static pthread_mutex_t mutex;
W#L6e#@G6Wm`2T0static int flag = 1;51Testing软件测试网~ g9x K)r2V
 51Testing软件测试网l8N^jaa'HB'D
void * thr_fn(void * arg)
Y D0d*W-@ vzI#K ^7C@0{51Testing软件测试网 Z:Qe jOa'a/z x7F5m ~
  struct timeval now;51Testing软件测试网l4_8K qYVQZ
  struct timespec outtime;
c!_'sZ;YmmBqC0  pthread_mutex_lock(&mutex);51Testing软件测试网J(g/l6K0`#Qe!~
  while (flag) {51Testing软件测试网J8AbXq7R6I
    printf("*****\n");51Testing软件测试网T:E }6Ky
    gettimeofday(&now, NULL);
5m&f&N2coI0yfZ)B0    outtime.tv_sec = now.tv_sec + 5;51Testing软件测试网r cd:u3fM
    outtime.tv_nsec = now.tv_usec * 1000;51Testing软件测试网[4F;B`-]
    pthread_cond_timedwait(&cond, &mutex, &outtime);
?,^+` b+hBTv0  }51Testing软件测试网+cKEv#_p O1b
  pthread_mutex_unlock(&mutex);51Testing软件测试网.K)k4JWS;c
  printf("cond thread exit\n");
IH.o1zW0}51Testing软件测试网&R"A-d {#` e
 51Testing软件测试网ao:hQ7a.j H U
int main(void)51Testing软件测试网'zB3f%Ia8U
{51Testing软件测试网~z#_+D _.o)io(W9G
  pthread_mutex_init(&mutex, NULL);
m/UK-sF8Pe&G0  pthread_cond_init(&cond, NULL);
W$jU P$FI5V0  if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) {51Testing软件测试网f:~D$tZ p
    printf("error when create pthread,%d\n", errno);
-K%FQ$h7G/e)gh:n0    return 1;
SY:} @8I{-Rx0  }51Testing软件测试网[ _%G/w`![b:h
  char c ;51Testing软件测试网1ncOH6V$Y&H!n
  while ((c = getchar()) != 'q');
#X}8HJ/t0  printf("Now terminate the thread!\n");

s)s5VR| Y051Testing软件测试网`hIe#kGc*G+z

  pthread_mutex_lock(&mutex);51Testing软件测试网d1^ xK&]i[,N}b
  flag = 0;
!kg](xV&bH0  pthread_cond_signal(&cond);
)f6vR'n(b `5x'l3R0  pthread_mutex_unlock(&mutex);
5O&P%_sG0q.E0  printf("Wait for thread to exit\n");
Ov]*T;\rY i0  pthread_join(thread, NULL);51Testing软件测试网3q}0n y E f#w
  printf("Bye\n");51Testing软件测试网)Cy)j}#n'D?
  return 0;
s9an V L&E0}
51Testing软件测试网7vi5CI u)B

51Testing软件测试网$@1aI:Q jdW.hC2`k-b

  pthread_cond_timedwait()函数阻塞住调用该函数的线程,等待由cond指定的条件被触发(pthread_cond_broadcast() or pthread_cond_signal())。

PFotZ[C(l$Y0

+^,^C.M(IH0  当pthread_cond_timedwait()被调用时,调用线程必须已经锁住了mutex。函数 pthread_cond_timedwait()会对mutex进行【解锁和执行对条件的等待】(原子操作)。这里的原子意味着:解锁和执行条件的等待 是原则的,一体的。(In this case, atomically means with respect to the mutex andthe condition variable and other access by threads to those objectsthrough the pthread condition variable interfaces.)

/b'e^W8|0

*zT9j;z%G0  如果等待条件满足或超时,或线程被取消,调用线程需要在线程继续执行前先自动锁住mutex,如果没有锁住mutex,产生EPERM错误。即,该函数返回时,mutex已经被调用线程锁住。

3fb {O1P&DuI0

VYD+x4v0  等待的时间通过abstime参数(绝对系统时间,过了该时刻就超时)指定,超时则返回ETIMEDOUT错误码。开始等待后,等待时间不受系统时钟改变的影响。51Testing软件测试网{&n-TD#G0x A6^

Ne|#i[0  尽管时间通过秒和纳秒指定,系统时间是毫秒粒度的。需要根据调度和优先级原因,设置的时间长度应该比预想的时间要多或者少点。可以通过使用系统时钟接口gettimeofday()获得timeval结构体。51Testing软件测试网.OkI\/}u,Op#j


TAG:

 

评分:0

我来说两句

Open Toolbar