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

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

51Testing软件测试网 Q&Py%H'qO

  我只想要进程的某个线程休眠一段时间的,可是用sleep()是将整个进程都休眠的,这个可能就达不到,我们想要的效果了。目前我知道有三种方式:51Testing软件测试网#{&h@ yT2`E

6d2x1S*P oe2k0  1、usleep51Testing软件测试网E&g/O6Zu)\9y

y:u#~b5q*n0  这个是轻量级的,听说能可一实现线程休眠,我个人并不喜欢这种方式,所以我没有验证它的可行信(个人不推荐)。

}8rO"_Q1oJ0

|K"@[8Hu0  2、select51Testing软件测试网 Nz3v9yk#n I#]

51Testing软件测试网m i$|6bx%|i[

  这个可以,我也用过这种方式,它是在轮询。51Testing软件测试网GQ8mS {-L {.\ w}

51Testing软件测试网Z2NPb5V!f#K-B

  3、pthread_cond_timedwait51Testing软件测试网t Ei1{#` fe

nB7?3QN i.J0   采用pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t *mutex, const struct timespec *abstime)可以优雅的解决该问题,设置等待条件变量cond,如果超时,则返回;如果等待到条件变量cond,也返回。本文暂不将内部机理,仅演 示一个demo。51Testing软件测试网E4A R4c/V4B%p"z

51Testing软件测试网n5w(D)@de(Su V+p-a

  首先,看这段代码,thr_fn为一个线程函数:51Testing软件测试网p+L7W!z``

51Testing软件测试网.[9jd|"B|!b&^A

#include <stdio.h>51Testing软件测试网/b&V.k@;gn'B
#include <stdlib.h>
51Testing软件测试网$T[r4MM t1h-sW?

4cXE.t&tcu$dw0int flag = 1;51Testing软件测试网 \3T9zs)w
void * thr_fn(void * arg) {51Testing软件测试网e S~S`Z d pr(m
  while (flag){
P|!Q ~OR8K'L;n0    printf("******\n");51Testing软件测试网/YN ^2k6z T
    sleep(10);51Testing软件测试网uOSd6w'R
  }
1U;c1QYyU0  printf("sleeptestthread exit\n");51Testing软件测试网V){DPQe$JB
}51Testing软件测试网(W%uw,}}w)~
 
&Jg^Z'B;d Q0int main() {
A L6W"F6U X0  pthread_t thread;
X@f*S}5HwJ?,G0  if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) {
x$t}@/S0    printf("error when create pthread,%d\n", errno);51Testing软件测试网;WQ)c&Y,U_
    return 1;
k/Onb-ne|la0  }
8o CB5a,G:h0 51Testing软件测试网,P)O-D)`.e#K
  char c ;
mkb {n"jyr(u0  while ((c = getchar()) != 'q');51Testing软件测试网$b ^YPs6f T.c4V
 
\&q4v&q!R)j ?^H0  printf("Now terminate the thread!\n");51Testing软件测试网J9ZGm,X0h.W4?
  flag = 0;51Testing软件测试网)Y?A,J)i,q
  printf("Wait for thread to exit\n");51Testing软件测试网1O V3A;x5y/r~&[V
  pthread_join(thread, NULL);51Testing软件测试网(?6f5K7qk/] g*B U6AB%^
  printf("Bye\n");51Testing软件测试网 Ket%?H9~
  return 0;51Testing软件测试网c0w.H:b }Gf
}

.z*` S9[ec0
51Testing软件测试网J5Im B(kL8_X&kY

  输入q后,需要等线程从sleep中醒来(由挂起状态变为运行状态),即最坏情况要等10s,线程才会被join。采用sleep的缺点:不能及时唤醒线程。51Testing软件测试网_3H,]*erq:e:c

51Testing软件测试网vR W jW+j"D.|Y

  采用pthread_cond_timedwait函数实现的如下:

V]&}X%@(p!{{051Testing软件测试网,`MyNN

51Testing软件测试网mHI8H9ZH*tlO%?1O B

51Testing软件测试网!r|`Z)U3Q

#include <stdio.h>
5UH2M4s6E0#include <sys/time.h>51Testing软件测试网&|(@o&q(Xt4Bn:k
#include <unistd.h>
mc~9K/u6H0#include <pthread.h>
.},E!AOW}'Z:[^0#include <errno.h>51Testing软件测试网4KIcGm}1~
 51Testing软件测试网l)Xz\)s'{X/IC
static pthread_t thread;
P3p-],?%O\o0@DO0static pthread_cond_t cond;
~'v!JL4ByP0static pthread_mutex_t mutex;51Testing软件测试网\+pL.Q2ME
static int flag = 1;51Testing软件测试网 r0M+^Qd4HsR|8xB I
 51Testing软件测试网!X-e)N:{"yT
void * thr_fn(void * arg)51Testing软件测试网H;n@0t2ok^
{51Testing软件测试网:H(r#w3u/c
  struct timeval now;51Testing软件测试网I,I*I [},[m u6tS
  struct timespec outtime;51Testing软件测试网y,} ` [1I
  pthread_mutex_lock(&mutex);
5B.K0?M2c0  while (flag) {51Testing软件测试网faV3G!Cy!w
    printf("*****\n");51Testing软件测试网slak\;LA G^
    gettimeofday(&now, NULL);51Testing软件测试网"U]bW^dS b#Y
    outtime.tv_sec = now.tv_sec + 5;51Testing软件测试网9t@"@VeW*vk
    outtime.tv_nsec = now.tv_usec * 1000;
f^"qM/a0StI0    pthread_cond_timedwait(&cond, &mutex, &outtime);
bu:lb*qg TF c{y0  }
*O/~!KBQ)Sq6ZnZ&I)@0  pthread_mutex_unlock(&mutex);
I3}&W }$xE0  printf("cond thread exit\n");
a,QHS7y-P$q+e0}51Testing软件测试网v1pQN-K b Y
 51Testing软件测试网9Y4y#j P6p(|
int main(void)
hZ WG[-z+f5A0{51Testing软件测试网6I&{ \%t,S}dV_
  pthread_mutex_init(&mutex, NULL);51Testing软件测试网D6aL!W2LZ
  pthread_cond_init(&cond, NULL);
%ga)v(dGS0  if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) {
I\){7m Xd8V0    printf("error when create pthread,%d\n", errno);51Testing软件测试网-E8r.l1^F2s@,S4k
    return 1;
;Y1o g,x4xH)A7N0  }
],g7X:]t)oe0  char c ;
)j0U;E VP:M6HL|F0  while ((c = getchar()) != 'q');51Testing软件测试网:d5d }6{P^
  printf("Now terminate the thread!\n");
51Testing软件测试网d M^7H F \-Y)S

.e!`7Hy]$HO:@&V b0  pthread_mutex_lock(&mutex);
7WpP5b\a-U0  flag = 0;51Testing软件测试网!K'Lt3I%FM1qh,o!c
  pthread_cond_signal(&cond);51Testing软件测试网 ie8C `Ul xwX Wk_ T
  pthread_mutex_unlock(&mutex);51Testing软件测试网)Nt$f,nyhVKT {j
  printf("Wait for thread to exit\n");
m"f)_Apum![0  pthread_join(thread, NULL);51Testing软件测试网0i2kj_6X3C
  printf("Bye\n");51Testing软件测试网%XY4jn-_[e'[
  return 0;
T7o1j2n3^e&o Xs0}

nRC[{{8?0
51Testing软件测试网}b4Z}5Y T0KH

  pthread_cond_timedwait()函数阻塞住调用该函数的线程,等待由cond指定的条件被触发(pthread_cond_broadcast() or pthread_cond_signal())。51Testing软件测试网$OCy"_e([5{

S }I$s"b{ a0  当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.)

|(d F:q`i5B!jC2M051Testing软件测试网vRW oPFe

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

ck7m7f C.C8p0

t5kG4CXc} E-c0  等待的时间通过abstime参数(绝对系统时间,过了该时刻就超时)指定,超时则返回ETIMEDOUT错误码。开始等待后,等待时间不受系统时钟改变的影响。

J3J \^3QHsPu l0

2Y'zQ5zRQ0  尽管时间通过秒和纳秒指定,系统时间是毫秒粒度的。需要根据调度和优先级原因,设置的时间长度应该比预想的时间要多或者少点。可以通过使用系统时钟接口gettimeofday()获得timeval结构体。51Testing软件测试网&Gng,B?GPW,Vu


TAG:

 

评分:0

我来说两句

Open Toolbar