Try   HackMD

Pthread Scheduling, Fairness, Power, Performance

tags: C LANGUAGE linux pthread performance

Author: CrazyMonkey
email: kccddb@gmail.com
Date: 20220726
Copyright: CC BY-NC-SA

PART I

以前花一點時間快速的寫了這有點長的程式為了學的同學也為地球與萬物留一個好的空間.

這程式是臨時寫出來程式盡可能讓同學易懂為目的, 沒有考慮可讀性與可移植別的CPU 的問題

I. Mutex variables MUST be declared with type pthread_mutex_t, and must be initialized before they can be used.
II. 了解 pthread_mutex_lock / pthread_mutex_unlock 與可能問題和代價
III. 程式執行效率與startvation 等問題

看 x% 要有統計機率的概念 這裡就不寫數學, 請思考Why?
不同 的 lock/unlock, 不同的 load (耗用 cpu 資源), 不同的 usleep(相當於讓出 cpu) 影響整個可能的效能需求!

如果 在 迴圈 中 影響更大

這裡的程式 主要是 展示 Fig. 3,4 的可能比較

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Fig. 1

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Fig. 2

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Fig. 3,4

Remark.

I1,I2 idle time
Assume
N1=N2
,
N10=N20
and
T1+I1=T2+I2
.

CASE 1:

N10(I10+N1(T1+I1))=N20(I10)+N10N1T1+N10N1I1

CASE 2:

N20(I20+N2(T2+I2))=N10(I10)+N10N2T2+N10N2I2

If

I2>I1 then
N10N1(I2I1)
, i.e., CASE 2 is better.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

/* Simple Random Sleep Example. Copyright 2018 GPL Author WhoAmI Random random_us random_us[0]....random_us[MAXTHREADS-1] You can test fprintf(stderr,...) $ ./tus_thread.exe -l 400 -u 3 -s 2> /dev/null $ ./tus_thread.exe -l 400 -u 4 -s 2> /dev/null */ #include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> #include <stdlib.h> #include<sys/time.h> //gcc tus_thread.c -Wall -o tus_thread -lpthread //int usleep(useconds_t usec); #define DEBUG00 1 #ifdef DEBUG00 #define debugp(x) x #else #define debugp(x) #endif #define MAXTHREADS 4 #define PTHREADID 100 #define LIMITMAX 20000 #define LIMITMIN 100 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; static int random_us[MAXTHREADS]; static pthread_mutex_t demomutex_p[MAXTHREADS]; //One must call pthread_mutex_init static int id_sum[2]; static int Loop[2]={500,50000}; static int silence=0; static int idle[MAXTHREADS]; /* Volatile and Optimization https://en.wikipedia.org/wiki/Volatile_(computer_programming) */ static volatile int P0=0; //demo, e.g., GPIO P0 static volatile int P1=0; //demo static volatile int *PDATA=NULL; static volatile int PID=0; static void pfirst(void *pthreadid,int id){ P0=1; PDATA=pthreadid; PID=id; } static int busyloop() { volatile int * ptr = (volatile int *) &P0; printf("Enter loop [One needs volatile due to gcc optimization.]\n"); /* function pointer, callback ,define,volatile and optimization) */ while(*ptr==0); printf("ptr-->%d id=%d addr=%p\n",*ptr,PID,PDATA); } static int noploop(int id,int count){ int i; time_t t; volatile int * ptr = (volatile int *) &P1; /* In fact, this (noploop()) is not a NOP function. NOP https://en.wikipedia.org/wiki/NOP */ /* Demo only! Try cpu loading.*/ for(i=0;i<count;i++){ t=time(NULL); //usleep(1); fprintf(stderr,"[stderr=2: id=%d]time=%ld\n",id,t); if(*ptr==0xff)break; //demo } } static int getmstime(time_t *ms) { struct timeval tv; time_t t; if(gettimeofday(&tv,NULL)<0)return -1; t=(1000000 * (tv.tv_sec)+ tv.tv_usec)/1000; if(ms) *ms=t; return 0; } void *threadUS(void *pthreadid) { int *idp, id; int loop1,loop2; time_t t0,t1; idp = (int *) pthreadid; id = *idp; getmstime(&t0); for(loop1=0;loop1<Loop[0];loop1++) { if(usleep(random_us[id-PTHREADID])<0){ perror("usleep"); } pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop[1];loop2++){ if(id%2==0){ global_var--; id_sum[0]++; } else { global_var++; id_sum[1]++; } } pthread_mutex_unlock(&demomutex); } getmstime(&t1); if(!silence)printf("thread %d: usleep=[%d] usec,ExitTime=%d msecs global_var=%d [%d]\n",id-PTHREADID,random_us[id-PTHREADID],t1-t0,global_var,id_sum[(id-PTHREADID)%2]); pfirst(pthreadid,id); pthread_exit((void*) pthreadid); } void *UnfairThreads(void *pthreadid) { int *idp, id; int loop1,loop2; time_t t0,t1; idp = (int *) pthreadid; id = *idp; getmstime(&t0); pthread_mutex_lock(&demomutex_p[0]); for(loop1=0;loop1<Loop[0];loop1++) { if(usleep(random_us[id-PTHREADID])<0){ perror("usleep"); } pthread_mutex_lock(&demomutex_p[1]); for(loop2=0;loop2<Loop[1];loop2++){ if(id%2==0){ global_var--; id_sum[0]++; } else { global_var++; id_sum[1]++; } } pthread_mutex_unlock(&demomutex_p[1]); } pthread_mutex_unlock(&demomutex_p[0]); getmstime(&t1); if(!silence)printf("Uthread %d: usleep=[%d] usec,ExitTime=%d msecs global_var=%d [%d]\n",id-PTHREADID,random_us[id-PTHREADID],t1-t0,global_var,id_sum[(id-PTHREADID)%2]); pfirst(pthreadid,id); pthread_exit((void*) pthreadid); } void *threadError(void *pthreadid) { int *idp, id; int loop1,loop2; time_t t0,t1; idp = (int *) pthreadid; id = *idp; getmstime(&t0); for(loop1=0;loop1<Loop[0];loop1++) { if(usleep(random_us[id-PTHREADID])<0){ perror("usleep"); } // pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop[1];loop2++){ if(id%2==0){ global_var--; id_sum[0]++; } else { global_var++; id_sum[1]++; } } // pthread_mutex_unlock(&demomutex); } getmstime(&t1); if(!silence)printf("thread %d: usleep=[%d] usec,ExitTime=%d msecs global_var=%d [%d]\n",id-PTHREADID,random_us[id-PTHREADID],t1-t0,global_var,id_sum[(id-PTHREADID)%2]); pfirst(pthreadid,id); pthread_exit((void*) pthreadid); } void *threadIdle(void *pthreadid) { int *idp, id; int loop1,loop2; time_t t0,t1; idp = (int *) pthreadid; id = *idp; getmstime(&t0); for(loop1=0;loop1<Loop[0];loop1++) { #if 0 if(usleep(random_us[id-PTHREADID])<0){ perror("usleep"); } #endif noploop(id,idle[id-PTHREADID]); pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop[1];loop2++){ if(id%2==0){ global_var--; id_sum[0]++; } else { global_var++; id_sum[1]++; } } pthread_mutex_unlock(&demomutex); } getmstime(&t1); //if(!silence)printf("thread %d: usleep=[%d] usec,ExitTime=%d msecs global_var=%d [%d]\n",id-PTHREADID,random_us[id-PTHREADID],t1-t0,global_var,id_sum[(id-PTHREADID)%2]); if(!silence)printf("thread %d: %d [%d] loops,ExitTime=%d msecs global_var=%d [%d]\n",id-PTHREADID,Loop[0],(Loop[0]*idle[id-PTHREADID]),t1-t0,global_var,id_sum[(id-PTHREADID)%2]); pfirst(pthreadid,id); pthread_exit((void*) pthreadid); } void *threadIdleb(void *pthreadid) { int *idp, id; int loop1,loop2; time_t t0,t1; idp = (int *) pthreadid; id = *idp; getmstime(&t0); for(loop1=0;loop1<Loop[0];loop1++) { #if 0 if(usleep(random_us[id-PTHREADID])<0){ perror("usleep"); } #endif pthread_mutex_lock(&demomutex); noploop(id,idle[id-PTHREADID]); for(loop2=0;loop2<Loop[1];loop2++){ if(id%2==0){ global_var--; id_sum[0]++; } else { global_var++; id_sum[1]++; } } pthread_mutex_unlock(&demomutex); } getmstime(&t1); //if(!silence)printf("thread %d: usleep=[%d] usec,ExitTime=%d msecs global_var=%d [%d]\n",id-PTHREADID,random_us[id-PTHREADID],t1-t0,global_var,id_sum[(id-PTHREADID)%2]); if(!silence)printf("thread %d: %d [%d] loops,ExitTime=%d msecs global_var=%d [%d]\n",id-PTHREADID,Loop[0],(Loop[0]*idle[id-PTHREADID]),t1-t0,global_var,id_sum[(id-PTHREADID)%2]); pfirst(pthreadid,id); pthread_exit((void*) pthreadid); } /* function pointers: https://en.wikipedia.org/wiki/Function_pointer */ typedef void * (*MYthread)(void *); static MYthread mythread[] ={&threadUS,&UnfairThreads, &threadError,threadIdle,threadIdleb,NULL}; int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; unsigned int seed; unsigned int us; int mode=0; time_t t0,t1; time_t total; time_t diff; int idlemax=0; for(i=0;i<argc;i++){ if(strcmp(argv[i],"-s")==0)silence=!0; if(strcmp(argv[i],"-l")==0)Loop[0]=atoi(argv[++i]); if(strcmp(argv[i],"-l2")==0)Loop[1]=atoi(argv[++i]); if(strcmp(argv[i],"-u")==0)mode=atoi(argv[++i]); if(strcmp(argv[i],"-h")==0){ printf("\nUsage:\n%s [-s] [-l 500 (%d)] [-l2 50000 (%d)][-u 0] [-h]\n",argv[0],Loop[0],Loop[1]); exit(EXIT_FAILURE); } } if(!silence)printf("Loop[0]=%d,Loop[1]=%d,mode=%d\n",Loop[0],Loop[1],mode); for(i=0;i<MAXTHREADS;i++){ if(pthread_mutex_init(&demomutex_p[i],NULL)<0){ perror("pthread_mutex_init"); exit(EXIT_FAILURE); } } seed=time(NULL); srandom(seed); us=0; for(i=0; i<MAXTHREADS;i++){ random_us[i]= random()%LIMITMAX+LIMITMIN; //random us if(!silence) printf("random_us[%d]=%d ",i,random_us[i]); if(random_us[i]>us)us=random_us[i]; //find the maximum } for(i=0; i<MAXTHREADS;i++){ idle[i]= random()%100+10; if(!silence) printf("idle[%d]=%d ",i,idle[i]); if(idle[i]>idlemax)idlemax=idle[i]; } if(!silence)printf("\n max us=%d, max idle=%d\n",us, idlemax); global_var=0; id_sum[0]=0; id_sum[1]=0; getmstime(&t0); for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; pthread_create(&child[i], NULL, mythread[mode], (void *) &id[i]); } if(mode==2)busyloop(); for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { debugp( if(!silence)printf("thread %d + %d, status=%ld, %p\n",i,PTHREADID,(long)status,status)); } else { perror("pthread"); } } getmstime(&t1); diff=t1-t0; for(i=0;i<MAXTHREADS;i++){ pthread_mutex_destroy(&demomutex_p[i]); } total=((us)*(Loop[0]))/1000; printf("[%d]global_var=%d, max us=%d usecs,loop=[%d,%d], sleep ~ %d msecs, %ld msecs (%d,%d)\n",mode,global_var,us,Loop[0],Loop[1],total,diff,id_sum[0],id_sum[1]); exit(EXIT_SUCCESS); }

簡單的 Makefile

CC = gcc AR = ar RANLIB = ranlib STRIP = strip CFLAGS = -Wall -DDEBUG0 LDFLAGS= -lpthread all: thread threads thread: tus_thread.c ${CC} tus_thread.c ${CFLAGS} -o tus_thread ${LDFLAGS} ${STRIP} tus_thread demo: tus_thread.c ${CC} tus_thread.c -o tus_thread ${LDFLAGS} threads: tus_thread.c ${CC} tus_thread.c -static ${CFLAGS} -o tus_thread_s ${LDFLAGS} ${CC} tus_thread.c -c ${AR} -rcs lib/mylib.a tus_thread.o ## ${STRIP} tus_thread_s ## ${RANLIB} lib/mylib.a ls -l tus_thread_s ${AR} -tv lib/mylib.a threadso:thread ${CC} -shared tus_thread -o lib/libdemo.so # objdump -p libdemo.so clean: rm tus_thread tus_thread_s

$ ./tus_thread.exe -l 400 -u 3 -s 2> /dev/null
$ ./tus_thread.exe -l 400 -u 4 -s 2> /dev/null

的結果
"sleep ~ " 這裏沒太大意義!!! 後面有用


laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 3 -s 2> /dev/null
[3]global_var=0, max us=13763 usecs,loop=[400,50000], sleep ~ 5505 msecs, 468 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 3 -s 2> /dev/null
[3]global_var=0, max us=17179 usecs,loop=[400,50000], sleep ~ 6871 msecs, 517 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 4 -s 2> /dev/null
[4]global_var=0, max us=13931 usecs,loop=[400,50000], sleep ~ 5572 msecs, 430 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 4 -s 2> /dev/null
[4]global_var=0, max us=15482 usecs,loop=[400,50000], sleep ~ 6192 msecs, 457 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 4 2> /dev/null
Loop[0]=400,Loop[1]=50000,mode=4
random_us[0]=2656 random_us[1]=13007 random_us[2]=2327 random_us[3]=14207 idle[0]=11 idle[1]=97 idle[2]=58 idle[3]=34
max us=14207, max idle=97
thread 0: 400 [4400] loops,ExitTime=427 msecs global_var=-150000 [39800000]
thread 0 + 100, status=4294953872, 0xffffcb90
thread 1: 400 [38800] loops,ExitTime=427 msecs global_var=-50000 [39800000]
thread 1 + 100, status=4294953876, 0xffffcb94
thread 2: 400 [23200] loops,ExitTime=427 msecs global_var=-50000 [40000000]
thread 2 + 100, status=4294953880, 0xffffcb98
thread 3: 400 [13600] loops,ExitTime=425 msecs global_var=0 [40000000]
thread 3 + 100, status=4294953884, 0xffffcb9c
[4]global_var=0, max us=14207 usecs,loop=[400,50000], sleep ~ 5682 msecs, 433 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 4 2> /dev/null
Loop[0]=400,Loop[1]=50000,mode=4
random_us[0]=7570 random_us[1]=20011 random_us[2]=13825 random_us[3]=16133 idle[0]=97 idle[1]=106 idle[2]=54 idle[3]=91
max us=20011, max idle=106
thread 1: 400 [42400] loops,ExitTime=501 msecs global_var=600000 [35900000]
thread 0: 400 [38800] loops,ExitTime=547 msecs global_var=0 [36500000]
thread 0 + 100, status=4294953872, 0xffffcb90
thread 1 + 100, status=4294953876, 0xffffcb94
thread 2: 400 [21600] loops,ExitTime=525 msecs global_var=-50000 [40000000]
thread 2 + 100, status=4294953880, 0xffffcb98
thread 3: 400 [36400] loops,ExitTime=526 msecs global_var=0 [40000000]
thread 3 + 100, status=4294953884, 0xffffcb9c
[4]global_var=0, max us=20011 usecs,loop=[400,50000], sleep ~ 8004 msecs, 594 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 3 2> /dev/null
Loop[0]=400,Loop[1]=50000,mode=3
random_us[0]=7844 random_us[1]=4460 random_us[2]=10984 random_us[3]=1473 idle[0]=91 idle[1]=104 idle[2]=35 idle[3]=26
max us=10984, max idle=104
thread 3: 400 [10400] loops,ExitTime=279 msecs global_var=1850000 [32450000]
thread 2: 400 [14000] loops,ExitTime=303 msecs global_var=-150000 [33500000]
thread 0: 400 [36400] loops,ExitTime=478 msecs global_var=-200000 [40000000]
thread 0 + 100, status=4294953872, 0xffffcb90
thread 1: 400 [41600] loops,ExitTime=445 msecs global_var=0 [40000000]
thread 1 + 100, status=4294953876, 0xffffcb94
thread 2 + 100, status=4294953880, 0xffffcb98
thread 3 + 100, status=4294953884, 0xffffcb9c
[3]global_var=0, max us=10984 usecs,loop=[400,50000], sleep ~ 4393 msecs, 484 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 3 2> /dev/null
Loop[0]=400,Loop[1]=50000,mode=3
random_us[0]=7397 random_us[1]=19120 random_us[2]=8454 random_us[3]=12205 idle[0]=14 idle[1]=67 idle[2]=79 idle[3]=16
max us=19120, max idle=79
thread 0: 400 [5600] loops,ExitTime=177 msecs global_var=-550000 [30000000]
thread 0 + 100, status=4294953872, 0xffffcb90
thread 3: 400 [6400] loops,ExitTime=179 msecs global_var=200000 [30450000]
thread 1: 400 [26800] loops,ExitTime=294 msecs global_var=450000 [40000000]
thread 1 + 100, status=4294953876, 0xffffcb94
thread 2: 400 [31600] loops,ExitTime=295 msecs global_var=0 [40000000]
thread 2 + 100, status=4294953880, 0xffffcb98
thread 3 + 100, status=4294953884, 0xffffcb9c
[3]global_var=0, max us=19120 usecs,loop=[400,50000], sleep ~ 7648 msecs, 298 msecs (40000000,40000000)
laikc@laikc-PC ~
$


-u 2 因沒 mutex lock 結果是錯的.

注意
sleep ~ 6769 msecs, 6807 msecs
的差別
用 <<<注意部分>>> 觀察現象


laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 0
Loop[0]=400,Loop[1]=50000,mode=0
random_us[0]=16924 random_us[1]=11319 random_us[2]=7774 random_us[3]=12964 idle[0]=12 idle[1]=46 idle[2]=50 idle[3]=47
max us=16924, max idle=50
thread 2: usleep=[7774] usec,ExitTime=3203 msecs global_var=-3800000 [29400000]
thread 1: usleep=[11319] usec,ExitTime=4801 msecs global_var=4350000 [38450000]
thread 3: usleep=[12964] usec,ExitTime=5202 msecs global_var=4750000 [40000000]
thread 0: usleep=[16924] usec,ExitTime=6804 msecs global_var=0 [40000000]
thread 0 + 100, status=4294953872, 0xffffcb90
thread 1 + 100, status=4294953876, 0xffffcb94
thread 2 + 100, status=4294953880, 0xffffcb98
thread 3 + 100, status=4294953884, 0xffffcb9c
[0]global_var=0, max us=16924 usecs,loop=[400,50000], sleep ~ 6769 msecs, 6807 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 1
Loop[0]=400,Loop[1]=50000,mode=1
random_us[0]=18467 random_us[1]=12688 random_us[2]=615 random_us[3]=14749 idle[0]=34 idle[1]=35 idle[2]=22 idle[3]=29
max us=18467, max idle=35
Uthread 0: usleep=[18467] usec,ExitTime=7607 msecs global_var=-20000000 [20000000]
thread 0 + 100, status=4294953872, 0xffffcb90
Uthread 1: usleep=[12688] usec,ExitTime=12808 msecs global_var=0 [20000000]
thread 1 + 100, status=4294953876, 0xffffcb94
Uthread 2: usleep=[615] usec,ExitTime=13209 msecs global_var=-20000000 [40000000]
thread 2 + 100, status=4294953880, 0xffffcb98
Uthread 3: usleep=[14749] usec,ExitTime=19210 msecs global_var=0 [40000000]
thread 3 + 100, status=4294953884, 0xffffcb9c
[1]global_var=0, max us=18467 usecs,loop=[400,50000], sleep ~ 7386 msecs, 19213 msecs (40000000,40000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 400 -u 2
Loop[0]=400,Loop[1]=50000,mode=2
random_us[0]=3318 random_us[1]=1834 random_us[2]=991 random_us[3]=12407 idle[0]=37 idle[1]=17 idle[2]=55 idle[3]=108
max us=12407, max idle=108
Enter loop [One needs volatile due to gcc optimization.]
thread 2: usleep=[991] usec,ExitTime=427 msecs global_var=-15254674 [25160687]
ptr>1 id=102 addr=0xffffcb98
thread 1: usleep=[1834] usec,ExitTime=912 msecs global_var=-7928308 [23228504]
thread 0: usleep=[3318] usec,ExitTime=1629 msecs global_var=-14051909 [39810687]
thread 0 + 100, status=4294953872, 0xffffcb90
thread 1 + 100, status=4294953876, 0xffffcb94
thread 2 + 100, status=4294953880, 0xffffcb98
thread 3: usleep=[12407] usec,ExitTime=5220 msecs global_var=-201909 [39778504]
thread 3 + 100, status=4294953884, 0xffffcb9c
[2]global_var=-201909, max us=12407 usecs,loop=[400,50000], sleep ~ 4962 msecs, 5233 msecs (39810687,39778504)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -u 0
Loop[0]=600,Loop[1]=50000,mode=0
random_us[0]=2248 random_us[1]=12288 random_us[2]=13878 random_us[3]=15205 idle[0]=15 idle[1]=53 idle[2]=44 idle[3]=99
max us=15205, max idle=99
thread 0: usleep=[2248] usec,ExitTime=1802 msecs global_var=-23900000 [36400000]
thread 0 + 100, status=4294953872, 0xffffcb90
thread 1: usleep=[12288] usec,ExitTime=7802 msecs global_var=-3500000 [54350000]
thread 1 + 100, status=4294953876, 0xffffcb94
thread 2: usleep=[13878] usec,ExitTime=8402 msecs global_var=-3800000 [60000000]
thread 2 + 100, status=4294953880, 0xffffcb98
thread 3: usleep=[15205] usec,ExitTime=9607 msecs global_var=0 [60000000]
thread 3 + 100, status=4294953884, 0xffffcb9c
[0]global_var=0, max us=15205 usecs,loop=[600,50000], sleep ~ 9123 msecs, 9608 msecs (60000000,60000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -u 1
Loop[0]=600,Loop[1]=50000,mode=1
random_us[0]=15792 random_us[1]=11692 random_us[2]=18226 random_us[3]=5713 idle[0]=64 idle[1]=76 idle[2]=12 idle[3]=60
max us=18226, max idle=76
Uthread 0: usleep=[15792] usec,ExitTime=9600 msecs global_var=-30000000 [30000000]
thread 0 + 100, status=4294953872, 0xffffcb90
Uthread 1: usleep=[11692] usec,ExitTime=16803 msecs global_var=0 [30000000]
thread 1 + 100, status=4294953876, 0xffffcb94
Uthread 2: usleep=[18226] usec,ExitTime=28210 msecs global_var=-30000000 [60000000]
thread 2 + 100, status=4294953880, 0xffffcb98
Uthread 3: usleep=[5713] usec,ExitTime=31812 msecs global_var=0 [60000000]
thread 3 + 100, status=4294953884, 0xffffcb9c
[1]global_var=0, max us=18226 usecs,loop=[600,50000], sleep ~ 10935 msecs, 31815 msecs (60000000,60000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -u 2
Loop[0]=600,Loop[1]=50000,mode=2
random_us[0]=19363 random_us[1]=4483 random_us[2]=9353 random_us[3]=11492 idle[0]=73 idle[1]=95 idle[2]=99 idle[3]=69
max us=19363, max idle=99
Enter loop [One needs volatile due to gcc optimization.]
thread 1: usleep=[4483] usec,ExitTime=3057 msecs global_var=19809156 [42504123]
ptr>1 id=101 addr=0xffffcb94
thread 2: usleep=[9353] usec,ExitTime=6059 msecs global_var=9856364 [44980786]
thread 3: usleep=[11492] usec,ExitTime=7263 msecs global_var=11870552 [59904123]
thread 0: usleep=[19363] usec,ExitTime=12032 msecs global_var=-79448 [59930786]
thread 0 + 100, status=4294953872, 0xffffcb90
thread 1 + 100, status=4294953876, 0xffffcb94
thread 2 + 100, status=4294953880, 0xffffcb98
thread 3 + 100, status=4294953884, 0xffffcb9c
[2]global_var=-79448, max us=19363 usecs,loop=[600,50000], sleep ~ 11617 msecs, 12033 msecs (59930786,59904123)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -l2 10000 -u 2
Loop[0]=600,Loop[1]=10000,mode=2
random_us[0]=9492 random_us[1]=18489 random_us[2]=5057 random_us[3]=3619 idle[0]=25 idle[1]=18 idle[2]=73 idle[3]=44
max us=18489, max idle=73
Enter loop [One needs volatile due to gcc optimization.]
thread 3: usleep=[3619] usec,ExitTime=2425 msecs global_var=810225 [7269189]
ptr>1 id=103 addr=0xffffcb8c
thread 2: usleep=[5057] usec,ExitTime=3601 msecs global_var=-1676413 [9529663]
thread 0: usleep=[9492] usec,ExitTime=6001 msecs global_var=-2798993 [11929663]
thread 0 + 100, status=4294953856, 0xffffcb80
thread 1: usleep=[18489] usec,ExitTime=11415 msecs global_var=51007 [11999189]
thread 1 + 100, status=4294953860, 0xffffcb84
thread 2 + 100, status=4294953864, 0xffffcb88
thread 3 + 100, status=4294953868, 0xffffcb8c
[2]global_var=51007, max us=18489 usecs,loop=[600,10000], sleep ~ 11093 msecs, 11415 msecs (11929663,11999189)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -l2 10000 -u 0
Loop[0]=600,Loop[1]=10000,mode=0
random_us[0]=7091 random_us[1]=4172 random_us[2]=7876 random_us[3]=7913 idle[0]=21 idle[1]=84 idle[2]=41 idle[3]=36
max us=7913, max idle=84
thread 1: usleep=[4172] usec,ExitTime=3001 msecs global_var=2240000 [9740000]
thread 0: usleep=[7091] usec,ExitTime=4801 msecs global_var=0 [11990000]
thread 0 + 100, status=4294953856, 0xffffcb80
thread 1 + 100, status=4294953860, 0xffffcb84
thread 2: usleep=[7876] usec,ExitTime=4801 msecs global_var=-10000 [12000000]
thread 2 + 100, status=4294953864, 0xffffcb88
thread 3: usleep=[7913] usec,ExitTime=4801 msecs global_var=0 [12000000]
thread 3 + 100, status=4294953868, 0xffffcb8c
[0]global_var=0, max us=7913 usecs,loop=[600,10000], sleep ~ 4747 msecs, 4809 msecs (12000000,12000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -l2 10000 -u 1
Loop[0]=600,Loop[1]=10000,mode=1
random_us[0]=519 random_us[1]=6075 random_us[2]=18408 random_us[3]=3102 idle[0]=70 idle[1]=90 idle[2]=74 idle[3]=98
max us=18408, max idle=98
Uthread 0: usleep=[519] usec,ExitTime=600 msecs global_var=-6000000 [6000000]
thread 0 + 100, status=4294953856, 0xffffcb80
Uthread 1: usleep=[6075] usec,ExitTime=4800 msecs global_var=0 [6000000]
thread 1 + 100, status=4294953860, 0xffffcb84
Uthread 2: usleep=[18408] usec,ExitTime=16201 msecs global_var=-6000000 [12000000]
thread 2 + 100, status=4294953864, 0xffffcb88
Uthread 3: usleep=[3102] usec,ExitTime=18602 msecs global_var=0 [12000000]
thread 3 + 100, status=4294953868, 0xffffcb8c
[1]global_var=0, max us=18408 usecs,loop=[600,10000], sleep ~ 11044 msecs, 18609 msecs (12000000,12000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -l2 30000 -u 0 -s
[0]global_var=0, max us=10212 usecs,loop=[600,30000], sleep ~ 6127 msecs, 6604 msecs (36000000,36000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -l2 30000 -u 1 -s
[1]global_var=0, max us=17170 usecs,loop=[600,30000], sleep ~ 10302 msecs, 20417 msecs (36000000,36000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 600 -l2 30000 -u 2 -s
Enter loop [One needs volatile due to gcc optimization.]
ptr>1 id=102 addr=0xffffcb88
[2]global_var=-385592, max us=14602 usecs,loop=[600,30000], sleep ~ 8761 msecs, 9012 msecs (36000000,35612432)
laikc@laikc-PC ~
$
<<<注意部分>>>
laikc@laikc-PC ~
$ ./tus_thread.exe -l 800 -l2 30000 -u 0 -s
[0]global_var=0, max us=18523 usecs,loop=[800,30000], sleep ~ 14818 msecs, 15207 msecs (48000000,48000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 800 -l2 30000 -u 1 -s
[1]global_var=0, max us=16970 usecs,loop=[800,30000], sleep ~ 13576 msecs, 40830 msecs (48000000,48000000)
laikc@laikc-PC ~
$ ./tus_thread.exe -l 800 -l2 30000 -u 2 -s
Enter loop [One needs volatile due to gcc optimization.]
ptr>1 id=100 addr=0xffffcb80
[2]global_var=-817008, max us=17207 usecs,loop=[800,30000], sleep ~ 13765 msecs, 14460 msecs (47998151,47174473)

PART II

以下很長

tlock_qos.c


#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <string.h>

//gcc tlock_qos.c -Wall -o tlock_qos -lpthread

#define MAXTHREADS 4
#define PTHREADID 100
int global_var=0;
static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER;

char messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error***Why?"};
void *Hello(void *pthreadid)
{
int *idp, id;
int loop1,loop2;
int Loop1,Loop2;
time_t t0,t1;
// sleep(1);
idp = (int *) pthreadid;
id = *idp;

printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]);
// pthread_mutex_lock(&demomutex); <<<<This is a bad method!!! why?

//這是故意安排的, id=0,1,2,3 行為不同
if(id%20){
Loop1=1000;
Loop2=2000;
}else{
Loop2=1000;
Loop1=2000;
}
printf("Total=Loop1(%d)Loop2(%d)=%d\n",Loop1,Loop2,Loop1Loop2);
time(&t0);
for(loop1=0;loop1<Loop1;loop1++)
{
for(loop2=0;loop2<Loop2;loop2++){
pthread_mutex_lock(&demomutex); //better
if(id%2
0)global_var++;
else global_var;
pthread_mutex_unlock(&demomutex);
}
// printf("%d\n",global_var);
}

time(&t1);
//計算時間
printf("[%d,%d]Time=%d secs\n",t0,t1,t1-t0);
// pthread_mutex_unlock(&demomutex); <<<<This is a bad method
pthread_exit((void*) pthreadid);
}
int main(int argc, char *argv[])
{
pthread_t child[MAXTHREADS];
int id[MAXTHREADS];
int i;
int s;
void status;
// you can use pthread_mutex_init(demomutex,NULL).
for(i=0;i<MAXTHREADS;i++)
{
id[i]=i+PTHREADID;
printf("Create thread id= %d[index=%d]\n", id[i],i);
pthread_create(&child[i], NULL, Hello, (void ) &id[i]);
}
/
Wait for all threads to finish **/
for (i = 0; i < MAXTHREADS; i++)
{
s=pthread_join(child[i], &status);
if(s==0)
{
printf("thread %d, status=%ld\n",i,(long)status);
}
else
{
perror("pthread");
}
}
// pthread_mutex_destroy(&demomutex);
printf("global_var=%d\n",global_var);
//sleep(10);
}

cygwin64


laikc@laikc-PC ~
$ ./tlock_qos
Create thread id= 100[index=0]
Create thread id= 101[index=1]
My Thread's ID [100] Hello 0
Total=Loop1(1000)*Loop2(2000)=2000000
My Thread's ID [101] Hello 1
Total=Loop1(2000)*Loop2(1000)=2000000
Create thread id= 102[index=2]
My Thread's ID [102] Hello 2
Create thread id= 103[index=3]
Total=Loop1(1000)*Loop2(2000)=2000000
My Thread's ID [103] Hello 3
Total=Loop1(2000)*Loop2(1000)=2000000
[1535867576,1535867597]Time=21 secs
thread 0, status=4294953936
[1535867576,1535867597]Time=21 secs
[1535867576,1535867597]Time=21 secs
[1535867576,1535867597]Time=21 secs
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~


#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <string.h>

//gcc tlock_qos.c -Wall -o tlock_qos -lpthread

#define MAXTHREADS 4
#define PTHREADID 100
int global_var=0;
static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER;

char messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error***Why?"};
void *Hello(void *pthreadid)
{
int *idp, id;
int loop1,loop2;
int Loop1,Loop2;
time_t t0,t1;
// sleep(1);
idp = (int *) pthreadid;
id = *idp;

printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]);
// pthread_mutex_lock(&demomutex); <<<<This is a bad method!!! why?
if(id%20){
Loop1=1000;
Loop2=2000;
}else{
Loop2=1000;
Loop1=2000;
}
printf("Total=Loop1(%d)Loop2(%d)=%d\n",Loop1,Loop2,Loop1Loop2);
time(&t0);
for(loop1=0;loop1<Loop1;loop1++)
{
for(loop2=0;loop2<Loop2;loop2++){
pthread_mutex_lock(&demomutex); //better
if(id%2
0)global_var++;
else global_var;
pthread_mutex_unlock(&demomutex);
}
// printf("%d\n",global_var);
}

time(&t1);
printf("[%d,%d]Time=%d secs\n",t0,t1,t1-t0);
// pthread_mutex_unlock(&demomutex); <<<<This is a bad method
pthread_exit((void*) pthreadid);
}
void *Hello2(void *pthreadid)
{
int *idp, id;
int loop1,loop2;
int Loop1,Loop2;
time_t t0,t1;
// sleep(1);
idp = (int *) pthreadid;
id = *idp;

printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]);
// pthread_mutex_lock(&demomutex); <<<<This is a bad method!!! why?
if(id%2==0){
Loop1=1000;
Loop2=2000;
}else{
Loop2=1000;
Loop1=2000;
}
printf("Total=Loop1(%d)Loop2(%d)=%d\n",Loop1,Loop2,Loop1Loop2);
time(&t0);
for(loop1=0;loop1<Loop1;loop1++)
{
pthread_mutex_lock(&demomutex);
for(loop2=0;loop2<Loop2;loop2++){

if(id%2==0)global_var++;
else global_var;

}
pthread_mutex_unlock(&demomutex);
// printf("%d\n",global_var);
}

time(&t1);
printf("[%d,%d]Time=%d secs\n",t0,t1,t1-t0);
// pthread_mutex_unlock(&demomutex); <<<<This is a bad method
pthread_exit((void*) pthreadid);
}

int main(int argc, char *argv[])
{
pthread_t child[MAXTHREADS];
int id[MAXTHREADS];
int i;
int s;
void status;
// you can use pthread_mutex_init(demomutex,NULL).
for(i=0;i<MAXTHREADS;i++)
{
id[i]=i+PTHREADID;
printf("Create thread id= %d[index=%d]\n", id[i],i);
pthread_create(&child[i], NULL, Hello2, (void ) &id[i]);
}
/
Wait for all threads to finish **/
for (i = 0; i < MAXTHREADS; i++)
{
s=pthread_join(child[i], &status);
if(s==0)
{
printf("thread %d, status=%ld\n",i,(long)status);
}
else
{
perror("pthread");
}
}
// pthread_mutex_destroy(&demomutex);
printf("global_var=%d\n",global_var);
//sleep(10);
}


cygwin64


laikc@laikc-PC ~
$ ./tlock_qos2
Create thread id= 100[index=0]
My Thread's ID [100] Hello 0
Total=Loop1(1000)*Loop2(2000)=2000000
Create thread id= 101[index=1]
My Thread's ID [101] Hello 1
Total=Loop1(2000)*Loop2(1000)=2000000
Create thread id= 102[index=2]
My Thread's ID [102] Hello 2
Total=Loop1(1000)*Loop2(2000)=2000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(2000)*Loop2(1000)=2000000
[1535867970,1535867970]Time=0 secs
thread 0, status=4294953936
[1535867970,1535867970]Time=0 secs
[1535867970,1535867970]Time=0 secs
[1535867970,1535867970]Time=0 secs
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=0


#include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> //gcc tlock_qos3.c -Wall -o tlock_qos3 -lpthread #define MAXTHREADS 4 #define PTHREADID 100 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; char *messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error****Why?"}; void *Hello(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=1000; Loop2=2000; }else{ Loop2=1000; Loop1=2000; } printf("Total=Loop1(%d)*Loop2(%d)=%d\n",Loop1,Loop2,Loop1*Loop2); time(&t0); for(loop1=0;loop1<Loop1;loop1++) { for(loop2=0;loop2<Loop2;loop2++){ pthread_mutex_lock(&demomutex); if(id%2==0)global_var++; else global_var--; pthread_mutex_unlock(&demomutex); } // printf("%d\n",global_var); } time(&t1); printf("[%d,%d]Time=%d secs\n",t0,t1,t1-t0); // pthread_mutex_unlock(&demomutex); <<<<This is a bad method pthread_exit((void*) pthreadid); } void *Hello3(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=10000; }else{ Loop2=30000; Loop1=10000; } printf("Total=Loop1(%d)*Loop2(%d)=%d\n",Loop1,Loop2,Loop1*Loop2); time(&t0); for(loop1=0;loop1<Loop1;loop1++) { pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0)global_var++; else global_var--; } pthread_mutex_unlock(&demomutex); // printf("%d\n",global_var); } time(&t1); printf("[%d,%d]Time=%d secs\n",t0,t1,t1-t0); // pthread_mutex_unlock(&demomutex); <<<<This is a bad method pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; // you can use pthread_mutex_init(demomutex,NULL). for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, Hello3, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } // pthread_mutex_destroy(&demomutex); printf("global_var=%d\n",global_var); //sleep(10); }

注意 紅, 綠的結果! Why?


laikc@laikc-PC ~
$ ./tlock_qos3
Create thread id= 100[index=0]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(10000)=300000000
Create thread id= 101[index=1]
Create thread id= 102[index=2]
My Thread's ID [101] Hello 1
Total=Loop1(10000)*Loop2(30000)=300000000
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(10000)=300000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(10000)*Loop2(30000)=300000000
[1535868709,1535868711]Time=2 secs
[1535868709,1535868711]Time=2 secs
[1535868709,1535868712]Time=3 secs
thread 0, status=4294953936
thread 1, status=4294953940
[1535868709,1535868712]Time=3 secs
thread 2, status=4294953944
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~
$


以下注意 tlock_qos4.c pthread_mutex_lock 的位置!


#include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> //gcc tlock_qos4.c -Wall -o tlock_qos4 -lpthread #define MAXTHREADS 4 #define PTHREADID 100 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; char *messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error****Why?"}; void *Hello(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=1000; Loop2=2000; }else{ Loop2=1000; Loop1=2000; } printf("Total=Loop1(%d)*Loop2(%d)=%d\n",Loop1,Loop2,Loop1*Loop2); time(&t0); for(loop1=0;loop1<Loop1;loop1++) { for(loop2=0;loop2<Loop2;loop2++){ pthread_mutex_lock(&demomutex); //better if(id%2==0)global_var++; else global_var--; pthread_mutex_unlock(&demomutex); } // printf("%d\n",global_var); } time(&t1); printf("[%ld,%ld]Time=%ld secs\n",t0,t1,t1-t0); // pthread_mutex_unlock(&demomutex); <<<<This is a bad method pthread_exit((void*) pthreadid); } void *Hello4(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=10000; }else{ Loop2=30000; Loop1=10000; } printf("Total=Loop1(%d)*Loop2(%d)=%d\n",Loop1,Loop2,Loop1*Loop2); time(&t0); pthread_mutex_lock(&demomutex); for(loop1=0;loop1<Loop1;loop1++) { for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0)global_var++; else global_var--; } // printf("%d\n",global_var); } pthread_mutex_unlock(&demomutex); time(&t1); printf("[%ld,%ld]Time=%ld secs\n",t0,t1,t1-t0); // pthread_mutex_unlock(&demomutex); <<<<This is a bad method pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; // you can use pthread_mutex_init(demomutex,NULL). for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, Hello4, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } // pthread_mutex_destroy(&demomutex); printf("global_var=%d\n",global_var); //sleep(10); }

laikc@laikc-PC ~
$ ./tlock_qos4
Create thread id= 100[index=0]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(10000)=300000000
Create thread id= 101[index=1]
Create thread id= 102[index=2]
My Thread's ID [101] Hello 1
Total=Loop1(10000)*Loop2(30000)=300000000
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(10000)=300000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(10000)*Loop2(30000)=300000000
[1535870735,1535870735]Time=0 secs
thread 0, status=4294953936
[1535870735,1535870736]Time=1 secs
thread 1, status=4294953940
[1535870735,1535870737]Time=2 secs
thread 2, status=4294953944
[1535870735,1535870737]Time=2 secs
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~
$


starvation


#include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> //gcc tlock_qos5.c -Wall -o tlock_qos5 -lpthread #define MAXTHREADS 4 #define PTHREADID 100 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; char *messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error****Why?"}; void *Hello5(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=50000; }else{ Loop2=30000; Loop1=50000; } printf("Total=Loop1(%d)*Loop2(%d)=%d\n",Loop1,Loop2,Loop1*Loop2); time(&t0); pthread_mutex_lock(&demomutex); for(loop1=0;loop1<Loop1;loop1++) { for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0)global_var++; else global_var--; } // printf("%d\n",global_var); } pthread_mutex_unlock(&demomutex); time(&t1); printf("[%ld,%ld]Time=%ld secs\n",t0,t1,t1-t0); // pthread_mutex_unlock(&demomutex); <<<<This is a bad method pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; // you can use pthread_mutex_init(demomutex,NULL). for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, Hello5, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } // pthread_mutex_destroy(&demomutex); printf("global_var=%d\n",global_var); //sleep(10); }

cygwin64 環境


laikc@laikc-PC ~
$ ./tlock_qos5
Create thread id= 100[index=0]
Create thread id= 101[index=1]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(50000)=1500000000
My Thread's ID [101] Hello 1
Total=Loop1(50000)*Loop2(30000)=1500000000
Create thread id= 102[index=2]
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(50000)=1500000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(50000)*Loop2(30000)=1500000000
[1535871126,1535871129]Time=3 secs
thread 0, status=4294953936
[1535871126,1535871133]Time=7 secs
thread 1, status=4294953940
[1535871126,1535871136]Time=10 secs
thread 2, status=4294953944
[1535871126,1535871139]Time=13 secs
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~


不同 pthread_mutex_lock 的影響


#include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> //gcc tlock_qos6.c -Wall -o tlock_qos6 -lpthread #define MAXTHREADS 4 #define PTHREADID 100 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; char *messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error****Why?"}; void *Hello5(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=50000; }else{ Loop2=30000; Loop1=50000; } printf("Total=Loop1(%d)*Loop2(%d)=%d\n",Loop1,Loop2,Loop1*Loop2); time(&t0); for(loop1=0;loop1<Loop1;loop1++) { pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0)global_var++; else global_var--; } pthread_mutex_unlock(&demomutex); // printf("%d\n",global_var); } time(&t1); printf("[%ld,%ld]Time=%ld secs\n",t0,t1,t1-t0); pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; // you can use pthread_mutex_init(demomutex,NULL). for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, Hello5, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } // pthread_mutex_destroy(&demomutex); printf("global_var=%d\n",global_var); //sleep(10); }

cygwin64 注意藍色與綠色的差別


laikc@laikc-PC ~
$ ./tlock_qos6
Create thread id= 100[index=0]
Create thread id= 101[index=1]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(50000)=1500000000
Create thread id= 102[index=2]
My Thread's ID [101] Hello 1
Total=Loop1(50000)*Loop2(30000)=1500000000
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(50000)=1500000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(50000)*Loop2(30000)=1500000000
[1535874332,1535874343]Time=11 secs
thread 0, status=4294953936
[1535874332,1535874343]Time=11 secs
[1535874332,1535874346]Time=14 secs
thread 1, status=4294953940
thread 2, status=4294953944
[1535874332,1535874346]Time=14 secs
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~


tlock_qos7 與上面tlock_qos6比較! Why?


#include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> //gcc tlock_qos7.c -Wall -o tlock_qos7 -lpthread #define MAXTHREADS 4 #define PTHREADID 100 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t demomutex2=PTHREAD_MUTEX_INITIALIZER; char *messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error****Why?"}; void *Hello5(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=50000; }else{ Loop2=30000; Loop1=50000; } printf("Total=Loop1(%d)*Loop2(%d)=%d\n",Loop1,Loop2,Loop1*Loop2); time(&t0); pthread_mutex_lock(&demomutex2); for(loop1=0;loop1<Loop1;loop1++) { pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0)global_var++; else global_var--; } pthread_mutex_unlock(&demomutex); // printf("%d\n",global_var); } pthread_mutex_unlock(&demomutex2); time(&t1); printf("[%ld,%ld]Time=%ld secs\n",t0,t1,t1-t0); pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; // you can use pthread_mutex_init(demomutex,NULL). for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, Hello5, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } // pthread_mutex_destroy(&demomutex); printf("global_var=%d\n",global_var); //sleep(10); }

laikc@laikc-PC ~
$ ./tlock_qos7
Create thread id= 100[index=0]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(50000)=1500000000
Create thread id= 101[index=1]
My Thread's ID [101] Hello 1
Create thread id= 102[index=2]
Total=Loop1(50000)*Loop2(30000)=1500000000
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(50000)=1500000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(50000)*Loop2(30000)=1500000000
[1535875639,1535875642]Time=3 secs
thread 0, status=4294953936
[1535875639,1535875646]Time=7 secs
thread 1, status=4294953940
[1535875639,1535875649]Time=10 secs
thread 2, status=4294953944
[1535875639,1535875653]Time=14 secs
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~
$

laikc@laikc-PC ~
$ ./tlock_qos7
Create thread id= 100[index=0]
Create thread id= 101[index=1]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(50000)=1500000000
Create thread id= 102[index=2]
My Thread's ID [101] Hello 1
Total=Loop1(50000)*Loop2(30000)=1500000000
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(50000)=1500000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(50000)*Loop2(30000)=1500000000
[1535875838,1535875841]Time=3 secs
thread 0, status=4294953936
[1535875838,1535875845]Time=7 secs
thread 1, status=4294953940
[1535875838,1535875849]Time=11 secs
thread 2, status=4294953944
[1535875838,1535875852]Time=14 secs
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~
$


再修改 Hello5 更動 Loop1, Loop2


void *Hello5(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=90000; }else{ Loop2=30000; Loop1=90000; } printf("Total=Loop1(%d)*Loop2(%d)=%ld\n",Loop1,Loop2,Loop1*Loop2); time(&t0); pthread_mutex_lock(&demomutex2); for(loop1=0;loop1<Loop1;loop1++) { pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0)global_var++; else global_var--; } pthread_mutex_unlock(&demomutex); // printf("%d\n",global_var); } pthread_mutex_unlock(&demomutex2); time(&t1); printf("thread %d[%ld,%ld]Time=%ld secs\n",id-PTHREADID,t0,t1,t1-t0); pthread_exit((void*) pthreadid); }

laikc@laikc-PC ~
$ ./tlock_qos8
Create thread id= 100[index=0]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 101[index=1]
My Thread's ID [101] Hello 1
Create thread id= 102[index=2]
Total=Loop1(90000)*Loop2(30000)=2700000000
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 0[1535877997,1535878003]Time=6 secs
thread 0, status=4294953936
thread 1[1535877997,1535878011]Time=14 secs
thread 1, status=4294953940
thread 2[1535877997,1535878017]Time=20 secs
thread 2, status=4294953944
thread 3[1535877997,1535878024]Time=27 secs
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~
$


再修改 Hello5 結果變更不好!!! Why?


void *Hello5(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=90000; }else{ Loop2=30000; Loop1=90000; } printf("Total=Loop1(%d)*Loop2(%d)=%ld\n",Loop1,Loop2,Loop1*Loop2); time(&t0); // pthread_mutex_lock(&demomutex2); for(loop1=0;loop1<Loop1;loop1++) { pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0)global_var++; else global_var--; } pthread_mutex_unlock(&demomutex); // printf("%d\n",global_var); } // pthread_mutex_unlock(&demomutex2); time(&t1); printf("thread %d[%ld,%ld]Time=%ld secs\n",id-PTHREADID,t0,t1,t1-t0); pthread_exit((void*) pthreadid); }

laikc@laikc-PC ~
$ ./tlock_qos9
Create thread id= 100[index=0]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 101[index=1]
Create thread id= 102[index=2]
My Thread's ID [101] Hello 1
Total=Loop1(90000)*Loop2(30000)=2700000000
Create thread id= 103[index=3]
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
My Thread's ID [103] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 0[1535878278,1535878295]Time=17 secs
thread 0, status=4294953936
thread 2[1535878278,1535878295]Time=17 secs
thread 3[1535878278,1535878304]Time=26 secs
thread 1[1535878278,1535878304]Time=26 secs
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~
$


以下再修改 Hello5 結果在 cygwin執行 變非常不好!!! Why?


void *Hello5(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=90000; }else{ Loop2=30000; Loop1=90000; } printf("Total=Loop1(%d)*Loop2(%d)=%ld\n",Loop1,Loop2,Loop1*Loop2); time(&t0); // pthread_mutex_lock(&demomutex2); for(loop1=0;loop1<Loop1;loop1++) { for(loop2=0;loop2<Loop2;loop2++){ pthread_mutex_lock(&demomutex); if(id%2==0)global_var++; else global_var--; pthread_mutex_unlock(&demomutex); } // printf("%d\n",global_var); } // pthread_mutex_unlock(&demomutex2); time(&t1); printf("thread %d[%ld,%ld]Time=%ld secs\n",id-PTHREADID,t0,t1,t1-t0); pthread_exit((void*) pthreadid); }

上面這個Hello5請自行修改, 自行加至 main()測試! 於我 cygwin 很久!!!



取消 pthread_mutex_lock / pthread_mutex_unlock
(當然答案是錯的), 也注意 pthread 離開的順序!!!


void *Hello5(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=90000; }else{ Loop2=30000; Loop1=90000; } printf("Total=Loop1(%d)*Loop2(%d)=%ld\n",Loop1,Loop2,Loop1*Loop2); time(&t0); // pthread_mutex_lock(&demomutex2); for(loop1=0;loop1<Loop1;loop1++) { for(loop2=0;loop2<Loop2;loop2++){ //pthread_mutex_lock(&demomutex); if(id%2==0)global_var++; else global_var--; //pthread_mutex_unlock(&demomutex); } // printf("%d\n",global_var); } // pthread_mutex_unlock(&demomutex2); time(&t1); printf("thread %d[%ld,%ld]Time=%ld secs\n",id-PTHREADID,t0,t1,t1-t0); pthread_exit((void*) pthreadid); }

laikc@laikc-PC ~
$ ./tlock_qos_0
Create thread id= 100[index=0]
My Thread's ID [100] Hello 0
Create thread id= 101[index=1]
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 102[index=2]
My Thread's ID [101] Hello 1
Total=Loop1(90000)*Loop2(30000)=2700000000
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 103[index=3]
My Thread's ID [103] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 2[1535881313,1535881332]Time=19 secs
thread 1[1535881313,1535881341]Time=28 secs
thread 0[1535881313,1535881346]Time=33 secs
thread 0, status=4294953936
thread 1, status=4294953940
thread 2, status=4294953944
thread 3[1535881327,1535881350]Time=23 secs
thread 3, status=4294953948
global_var=173214879
laikc@laikc-PC ~
$

laikc@laikc-PC ~
$ ./tlock_qos_0
Create thread id= 100[index=0]
My Thread's ID [100] Hello 0
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 101[index=1]
My Thread's ID [101] Hello 1
Create thread id= 102[index=2]
Total=Loop1(90000)*Loop2(30000)=2700000000
My Thread's ID [102] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 103[index=3]
thread 0[1535881620,1535881639]Time=19 secs
My Thread's ID [103] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 0, status=4294953936
thread 1[1535881620,1535881645]Time=25 secs
thread 1, status=4294953940
thread 3[1535881639,1535881656]Time=17 secs
thread 2[1535881632,1535881657]Time=25 secs
thread 2, status=4294953944
thread 3, status=4294953948
global_var=787901792
laikc@laikc-PC ~
$


以下是特殊的 應用
id==0 thread global_var;
id 1,2,3 global_var++;
LIMITMAX 30000

這代表 一個queue, 3 個 thread 代表 input
1 個 thread 代表 output
*注意當其中的 thread ( 1,2,3) 有遇到 global_var>=LIMITMAX 就會結束!!!


#include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> //gcc tlock_queue.c -Wall -o tlock_queue -lpthread /* Mutex variables MUST be declared with type pthread_mutex_t, and must be initialized before they can be used. */ /* There are two ways to initialize a mutex variable: Statically, when it is declared. A. pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER; B. Dynamically, with the pthread_mutex_init() routine. */ /* The mutex is initially unlocked. */ #define MAXTHREADS 4 #define PTHREADID 0 #define LIMITMAX 30000 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t demomutex2=PTHREAD_MUTEX_INITIALIZER; char *messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error****Why?"}; void *Hello5(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); // pthread_mutex_lock(&demomutex); <<<<This is a bad method!!!!!!! why? if(id%2==0){ Loop1=30000; Loop2=90000; }else{ Loop2=30000; Loop1=90000; } printf("Total=Loop1(%d)*Loop2(%d)=%ld\n",Loop1,Loop2,Loop1*Loop2); time(&t0); // pthread_mutex_lock(&demomutex2); for(loop1=0;loop1<Loop1;loop1++) { pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop2;loop2++){ if(id==0){if(global_var>0)global_var--;} else global_var++; if(global_var>=LIMITMAX){ pthread_mutex_unlock(&demomutex); goto BREAK; } } pthread_mutex_unlock(&demomutex); } BREAK: printf("thread %d: %d\n",id-PTHREADID,global_var); // pthread_mutex_unlock(&demomutex2); time(&t1); printf("thread %d[%ld,%ld]Time=%ld secs\n",id-PTHREADID,t0,t1,t1-t0); pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; // you can use pthread_mutex_init(demomutex,NULL). for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, Hello5, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } // pthread_mutex_destroy(&demomutex); printf("global_var=%d\n",global_var); //sleep(10); }

以下是 cygwin 下的三種可能結果, 這裏 有 0, 30000, 30001 的差別是 Hello5 沒有詳細處理的問題. 可以了解為甚麼嗎?


laikc@laikc-PC ~
$ ./tlock_queue
Create thread id= 0[index=0]
My Thread's ID [0] Hello 0
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 1[index=1]
My Thread's ID [1] Hello 1
Total=Loop1(90000)*Loop2(30000)=2700000000
Create thread id= 2[index=2]
thread 1: 30000
thread 1[1535887988,1535887988]Time=0 secs
My Thread's ID [2] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 3[index=3]
My Thread's ID [3] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 2: 30000
thread 2[1535887988,1535887988]Time=0 secs
thread 3: 30000
thread 3[1535887988,1535887988]Time=0 secs
thread 0: 0
thread 0[1535887988,1535888002]Time=14 secs
thread 0, status=4294953936
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~
$ ./tlock_queue
Create thread id= 0[index=0]
My Thread's ID [0] Hello 0
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 1[index=1]
Create thread id= 2[index=2]
My Thread's ID [1] Hello 1
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 1: 30000
thread 1[1535888030,1535888030]Time=0 secs
My Thread's ID [2] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 3[index=3]
thread 2: 30000
thread 2[1535888030,1535888030]Time=0 secs
My Thread's ID [3] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 3: 30000
thread 3[1535888030,1535888030]Time=0 secs
thread 0: 0
thread 0[1535888030,1535888044]Time=14 secs
thread 0, status=4294953936
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=0
laikc@laikc-PC ~
$ ./tlock_queue
Create thread id= 0[index=0]
My Thread's ID [0] Hello 0
Create thread id= 1[index=1]
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 2[index=2]
My Thread's ID [1] Hello 1
Total=Loop1(90000)*Loop2(30000)=2700000000
My Thread's ID [2] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 3[index=3]
thread 1: 30000
thread 2: 30001
thread 1[1535888047,1535888047]Time=0 secs
thread 0: 30000
thread 2[1535888047,1535888047]Time=0 secs
thread 0[1535888047,1535888047]Time=0 secs
thread 0, status=4294953936
thread 1, status=4294953940
thread 2, status=4294953944
My Thread's ID [3] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 3: 30001
thread 3[1535888047,1535888047]Time=0 secs
thread 3, status=4294953948
global_var=30001
laikc@laikc-PC ~
$

也思考下面的問題(有點難!):


laikc@laikc-PC ~
$ ./tlock_queue
Create thread id= 0[index=0]
Create thread id= 1[index=1]
My Thread's ID [0] Hello 0
Total=Loop1(30000)*Loop2(90000)=2700000000
My Thread's ID [1] Hello 1
Total=Loop1(90000)*Loop2(30000)=2700000000
Create thread id= 2[index=2]
thread 1: 30000
thread 1[1535930757,1535930757]Time=0 secs
My Thread's ID [2] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 3[index=3]
thread 2: 30000
thread 2[1535930757,1535930757]Time=0 secs
My Thread's ID [3] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 3: 30000
thread 3[1535930757,1535930757]Time=0 secs
thread 0: 0
thread 0[1535930757,1535930764]Time=7 secs
thread 0, status=4294953936
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=0


laikc@laikc-PC ~
$ ./tlock_queue
Create thread id= 0[index=0]
My Thread's ID [0] Hello 0
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 1[index=1]
My Thread's ID [1] Hello 1
Create thread id= 2[index=2]
Total=Loop1(90000)*Loop2(30000)=2700000000
My Thread's ID [2] Hello 2
Total=Loop1(30000)*Loop2(90000)=2700000000
Create thread id= 3[index=3]
thread 1: 30000
thread 1[1535930781,1535930781]Time=0 secs
thread 2: 30001
thread 2[1535930781,1535930781]Time=0 secs
thread 0: 30000

thread 0[1535930781,1535930781]Time=0 secs
My Thread's ID [3] Hello 3
Total=Loop1(90000)*Loop2(30000)=2700000000
thread 3: 30001
thread 3[1535930781,1535930781]Time=0 secs
thread 0, status=4294953936
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=30001


請問
a. 有沒有可能於單一CPU的情況下出現 30002 ?
b. 出現 global_var=0 的機率是否最高? 為甚麼?


Weighted Round Robin (WRR)

也請注意 wrr[] 與時間的關係
Loop1=50000/wrr[id-PTHREADID];
運用 改變 Loop1 改變所需執行時間!! 也就是降低不同Loop1進而改變 thread [id-PTHREADID] 所需時間!!!
例如 wrr[1]=10
則 Loop1=5000.

例如 wrr[2]=50

則 Loop1=1000.


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

/* Simple Weighted Round Robin (WRR) Example. Copyright 2018 GPL Author WhoAmI Random Weight: 1~99 wrr[0]....wrr[MAXTHREADS-1] */ #include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> #include <stdlib.h> //gcc tlock_wrr.c -Wall -o tlock_wrr -lpthread #define MAXTHREADS 4 #define PTHREADID 0 #define LIMITMAX 30000 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t demomutex2=PTHREAD_MUTEX_INITIALIZER; static char *messages[MAXTHREADS+1]={"Hello 0","Hello 1","Hello 2","Hello 3","*****Error****Why?"}; static int wrr[MAXTHREADS+1]; static int id_sum[2]; void *HelloWRR(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop1,Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]); Loop1=50000/wrr[id-PTHREADID]; Loop2=90000; printf("Total=Loop1(%d)*Loop2(%d)=%ld\n",Loop1,Loop2,Loop1*Loop2); time(&t0); for(loop1=0;loop1<Loop1;loop1++) { pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0){ global_var--; id_sum[0]++; } else { global_var++; id_sum[1]++; } } pthread_mutex_unlock(&demomutex); } printf(">>>thread %d: weight=[%d] %d [%d]\n",id-PTHREADID,wrr[id-PTHREADID],global_var,id_sum[(id-PTHREADID)%2]); time(&t1); printf("thread %d: weight=[%d],[%ld,%ld]Time=%ld secs\n",id-PTHREADID,wrr[id-PTHREADID],t0,t1,t1-t0); pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; unsigned int seed; // you can use pthread_mutex_init(demomutex,NULL). seed=time(NULL); srandom(seed); for(i=0; i<MAXTHREADS;i++){ wrr[i]= random()%99+1; //random 1~99, weight printf("wrr[%d]=%d ",i,wrr[i]); } printf("\n"); global_var=0; id_sum[0]=0; id_sum[1]=0; for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, HelloWRR, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } // pthread_mutex_destroy(&demomutex); printf("global_var=%d, [%d - %d]=%d\n",global_var,id_sum[1],id_sum[0],id_sum[1]-id_sum[0]); //sleep(10); }

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

laikc@laikc-PC ~
$ ./tlock_wrr
wrr[0]=78 wrr[1]=10 wrr[2]=11 wrr[3]=50
Create thread id= 0[index=0]
My Thread's ID [0] Hello 0
Total=Loop1(641)*Loop2(90000)=57690000
Create thread id= 1[index=1]
Create thread id= 2[index=2]
My Thread's ID [1] Hello 1
Total=Loop1(5000)*Loop2(90000)=450000000
My Thread's ID [2] Hello 2
Total=Loop1(4545)*Loop2(90000)=409050000
Create thread id= 3[index=3]
My Thread's ID [3] Hello 3
Total=Loop1(1000)*Loop2(90000)=90000000

thread 0: weight=[78] -14220000 [101160000]
thread 0: weight=[78],[1535947431,1535947431]Time=0 secs
thread 0, status=4294953936
thread 3: weight=[50] 32400000 [180090000]
thread 3: weight=[50],[1535947431,1535947432]Time=1 secs
thread 2: weight=[11] 33030000 [466740000]
thread 2: weight=[11],[1535947431,1535947433]Time=2 secs
thread 1: weight=[10] 73260000 [540000000]
thread 1: weight=[10],[1535947431,1535947433]Time=2 secs
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=73260000, [540000000 - 466740000]=73260000
laikc@laikc-PC ~
$ ./tlock_wrr
wrr[0]=27 wrr[1]=7 wrr[2]=15 wrr[3]=38
Create thread id= 0[index=0]
Create thread id= 1[index=1]
My Thread's ID [0] Hello 0
Total=Loop1(1851)*Loop2(90000)=166590000
My Thread's ID [1] Hello 1
Total=Loop1(7142)*Loop2(90000)=642780000
Create thread id= 2[index=2]
Create thread id= 3[index=3]
My Thread's ID [2] Hello 2
Total=Loop1(3333)*Loop2(90000)=299970000
My Thread's ID [3] Hello 3
Total=Loop1(1315)*Loop2(90000)=118350000
thread 3: weight=[38] 90000 [236700000]
thread 3: weight=[38],[1535947436,1535947437]Time=1 secs
thread 0: weight=[27] -48150000 [333000000]
thread 0: weight=[27],[1535947436,1535947438]Time=2 secs
thread 0, status=4294953936
thread 2: weight=[15] -42660000 [466560000]
thread 2: weight=[15],[1535947436,1535947439]Time=3 secs
thread 1: weight=[7] 294570000 [761130000]
thread 1: weight=[7],[1535947436,1535947439]Time=3 secs
thread 1, status=4294953940
thread 2, status=4294953944
thread 3, status=4294953948
global_var=294570000, [761130000 - 466560000]=294570000
laikc@laikc-PC ~
$ ./tlock_wrr
wrr[0]=58 wrr[1]=40 wrr[2]=36 wrr[3]=46
Create thread id= 0[index=0]
My Thread's ID [0] Hello 0
Total=Loop1(862)*Loop2(90000)=77580000
Create thread id= 1[index=1]
Create thread id= 2[index=2]
My Thread's ID [1] Hello 1
Total=Loop1(1250)*Loop2(90000)=112500000
Create thread id= 3[index=3]
My Thread's ID [2] Hello 2
Total=Loop1(1388)*Loop2(90000)=124920000
My Thread's ID [3] Hello 3
Total=Loop1(1086)*Loop2(90000)=97740000
thread 0: weight=[58] -13230000 [141840000]
thread 0: weight=[58],[1535947442,1535947443]Time=1 secs
thread 0, status=4294953936
thread 3: weight=[46] 20250000 [195570000]
thread 3: weight=[46],[1535947442,1535947443]Time=1 secs
thread 1: weight=[40] 20250000 [210240000]
thread 1: weight=[40],[1535947442,1535947443]Time=1 secs
thread 1, status=4294953940
thread 2: weight=[36] 7740000 [202500000]
thread 2: weight=[36],[1535947442,1535947443]Time=1 secs
thread 2, status=4294953944
thread 3, status=4294953948
global_var=7740000, [210240000 - 202500000]=7740000


以下是將#define MAXTHREADS 4 改為 #define MAXTHREADS 8

記得 printf(" My Thread's ID [%d] %s\n", id, messages[id-PTHREADID]);
取消!!! My Thread's ID [5] (null) 就是沒刪除!


laikc@laikc-PC ~
$ ./tlock_wrr8
wrr[0]=27 wrr[1]=91 wrr[2]=99 wrr[3]=32 wrr[4]=14 wrr[5]=66 wrr[6]=22 wrr[7]=53
Create thread id= 0[index=0]
Create thread id= 1[index=1]
My Thread's ID [0] Hello 0
Total=Loop1(1851)Loop2(90000)=166590000
My Thread's ID [1] Hello 1
Total=Loop1(549)Loop2(90000)=49410000
Create thread id= 2[index=2]
My Thread's ID [2] Hello 2
Total=Loop1(505)Loop2(90000)=45450000
Create thread id= 3[index=3]
My Thread's ID [3] Hello 3
Total=Loop1(1562)Loop2(90000)=140580000
Create thread id= 4[index=4]
My Thread's ID [4] *****Error
Why?
Total=Loop1(3571)*Loop2(90000)=321390000
Create thread id= 5[index=5]
My Thread's ID [5] (null)
Total=Loop1(757)*Loop2(90000)=68130000
Create thread id= 6[index=6]
Create thread id= 7[index=7]
My Thread's ID [6] (null)
Total=Loop1(2272)*Loop2(90000)=204480000
My Thread's ID [7] (null)
Total=Loop1(943)*Loop2(90000)=84870000

thread 2: weight=[99] -180000 [181530000]
thread 2: weight=[99],[1535950621,1535950622]Time=1 secs
thread 1: weight=[91] 3780000 [197010000]
thread 1: weight=[91],[1535950621,1535950622]Time=1 secs
thread 5: weight=[66] 3780000 [253710000]
thread 5: weight=[66],[1535950621,1535950623]Time=2 secs
thread 7: weight=[53] -12870000 [287370000]
thread 7: weight=[53],[1535950621,1535950623]Time=2 secs
thread 3: weight=[32] -124020000 [342990000]
thread 3: weight=[32],[1535950621,1535950624]Time=3 secs
thread 0: weight=[27] -201690000 [544680000]
thread 0: weight=[27],[1535950621,1535950624]Time=3 secs
thread 0, status=4294953888
thread 1, status=4294953892
thread 2, status=4294953896
thread 3, status=4294953900
thread 6: weight=[22] -278010000 [621000000]
thread 6: weight=[22],[1535950621,1535950624]Time=3 secs
thread 4: weight=[14] -394920000 [737910000]
thread 4: weight=[14],[1535950621,1535950624]Time=3 secs
thread 4, status=4294953904
thread 5, status=4294953908
thread 6, status=4294953912
thread 7, status=4294953916
global_var=-394920000, [342990000 - 737910000]=-394920000
laikc@laikc-PC ~
$ ./tlock_wrr8
wrr[0]=58 wrr[1]=31 wrr[2]=24 wrr[3]=21 wrr[4]=25 wrr[5]=52 wrr[6]=36 wrr[7]=70
Create thread id= 0[index=0]
My Thread's ID [0] Hello 0
Total=Loop1(862)Loop2(90000)=77580000
Create thread id= 1[index=1]
My Thread's ID [1] Hello 1
Total=Loop1(1612)Loop2(90000)=145080000
Create thread id= 2[index=2]
My Thread's ID [2] Hello 2
Total=Loop1(2083)Loop2(90000)=187470000
Create thread id= 3[index=3]
Create thread id= 4[index=4]
My Thread's ID [3] Hello 3
Total=Loop1(2380)Loop2(90000)=214200000
My Thread's ID [4] *****Error
Why?
Total=Loop1(2000)*Loop2(90000)=180000000
Create thread id= 5[index=5]
My Thread's ID [5] (null)
Total=Loop1(961)*Loop2(90000)=86490000
Create thread id= 6[index=6]
Create thread id= 7[index=7]
My Thread's ID [6] (null)
Total=Loop1(1388)*Loop2(90000)=124920000
My Thread's ID [7] (null)
Total=Loop1(714)Loop2(90000)=64260000
thread 7: weight=[70] -90000 [257310000]
thread 7: weight=[70],[1535950626,1535950628]Time=2 secs
thread 0: weight=[58] -13140000 [309330000]
thread 0: weight=[58],[1535950626,1535950628]Time=2 secs
thread 0, status=4294953888
thread 5: weight=[52] -13230000 [323820000]
thread 5: weight=[52],[1535950626,1535950628]Time=2 secs
thread 6: weight=[36] -51570000 [452430000]
thread 6: weight=[36],[1535950626,1535950629]Time=3 secs
thread 1: weight=[31] -51660000 [440730000]
thread 1: weight=[31],[1535950626,1535950629]Time=3 secs
thread 1, status=4294953892
thread 4: weight=[25] -86760000 [562590000]
thread 4: weight=[25],[1535950626,1535950629]Time=3 secs
thread 2: weight=[24] -86760000 [569970000]
thread 2: weight=[24],[1535950626,1535950629]Time=3 secs
thread 2, status=4294953896
thread 3: weight=[21] -59940000 [510030000]
thread 3: weight=[21],[1535950626,1535950629]Time=3 secs
thread 3, status=4294953900
thread 4, status=4294953904
thread 5, status=4294953908
thread 6, status=4294953912
thread 7, status=4294953916
global_var=-59940000, [510030000 - 569970000]=-59940000
laikc@laikc-PC ~
$ ./tlock_wrr8
wrr[0]=43 wrr[1]=80 wrr[2]=66 wrr[3]=47 wrr[4]=9 wrr[5]=99 wrr[6]=17 wrr[7]=87
Create thread id= 0[index=0]
Create thread id= 1[index=1]
My Thread's ID [0] Hello 0
Total=Loop1(1162)Loop2(90000)=104580000
Create thread id= 2[index=2]
My Thread's ID [1] Hello 1
Total=Loop1(625)Loop2(90000)=56250000
My Thread's ID [2] Hello 2
Total=Loop1(757)Loop2(90000)=68130000
Create thread id= 3[index=3]
Create thread id= 4[index=4]
My Thread's ID [4] *****Error
Why?
Total=Loop1(5555)*Loop2(90000)=499950000
Create thread id= 5[index=5]
My Thread's ID [3] Hello 3
Total=Loop1(1063)*Loop2(90000)=95670000
Create thread id= 6[index=6]
My Thread's ID [5] (null)
Total=Loop1(505)*Loop2(90000)=45450000
My Thread's ID [6] (null)
Total=Loop1(2941)*Loop2(90000)=264690000
Create thread id= 7[index=7]
My Thread's ID [7] (null)
Total=Loop1(574)*Loop2(90000)=51660000
thread 5: weight=[99] -9540000 [182070000]
thread 5: weight=[99],[1535950633,1535950634]Time=1 secs
thread 7: weight=[87] -15750000 [201060000]
thread 7: weight=[87],[1535950633,1535950634]Time=1 secs
thread 1: weight=[80] -24030000 [209340000]
thread 1: weight=[80],[1535950633,1535950634]Time=1 secs
thread 2: weight=[66] -59760000 [281070000]
thread 2: weight=[66],[1535950633,1535950634]Time=1 secs
thread 0: weight=[43] -114390000 [362970000]
thread 0: weight=[43],[1535950633,1535950634]Time=1 secs
thread 0, status=4294953888
thread 1, status=4294953892
thread 2, status=4294953896
thread 3: weight=[47] -114840000 [249030000]
thread 3: weight=[47],[1535950633,1535950634]Time=1 secs
thread 3, status=4294953900
thread 6: weight=[17] -453240000 [702270000]
thread 6: weight=[17],[1535950633,1535950635]Time=2 secs
thread 4: weight=[9] -688320000 [937350000]
thread 4: weight=[9],[1535950633,1535950636]Time=3 secs
thread 4, status=4294953904
thread 5, status=4294953908
thread 6, status=4294953912
thread 7, status=4294953916
global_var=-688320000, [249030000 - 937350000]=-688320000
laikc@laikc-PC ~
$



#define MAXTHREADS 16

laikc@laikc-PC ~
$ gcc tlock_wrr16.c -o tlock_wrr16 -lpthread
laikc@laikc-PC ~
$ ./tlock_wrr16
wrr[0]=53 wrr[1]=54 wrr[2]=5 wrr[3]=78 wrr[4]=42 wrr[5]=63 wrr[6]=31 wrr[7]=15 wrr[8]=58 wrr[9]=93 wrr[10]=58 wrr[11]=15 wrr[12]=48 wrr[13]=1 wrr[14]=73 wrr[15]=93
Create thread id= 0[index=0]
Create thread id= 1[index=1]
My Thread's ID [0] Hello 0
Total=Loop1(943)Loop2(90000)=84870000
My Thread's ID [1] Hello 1
Create thread id= 2[index=2]
Total=Loop1(925)Loop2(90000)=83250000
My Thread's ID [2] Hello 2
Total=Loop1(10000)Loop2(90000)=900000000
Create thread id= 3[index=3]
My Thread's ID [3] Hello 3
Total=Loop1(641)Loop2(90000)=57690000
Create thread id= 4[index=4]
My Thread's ID [4] *****Error
Why?
Total=Loop1(1190)*Loop2(90000)=107100000
Create thread id= 5[index=5]
My Thread's ID [5] (null)
Total=Loop1(793)*Loop2(90000)=71370000
Create thread id= 6[index=6]
My Thread's ID [6] (null)
Total=Loop1(1612)*Loop2(90000)=145080000
Create thread id= 7[index=7]
My Thread's ID [7] (null)
Total=Loop1(3333)*Loop2(90000)=299970000
Create thread id= 8[index=8]
My Thread's ID [8] (null)
Total=Loop1(862)*Loop2(90000)=77580000
Create thread id= 9[index=9]
Create thread id= 10[index=10]
My Thread's ID [10] (null)
Total=Loop1(862)*Loop2(90000)=77580000
Create thread id= 11[index=11]
My Thread's ID [9] (null)
Total=Loop1(537)*Loop2(90000)=48330000
My Thread's ID [11] (null)
Total=Loop1(3333)*Loop2(90000)=299970000
Create thread id= 12[index=12]
Create thread id= 13[index=13]
My Thread's ID [12] (null)
Total=Loop1(1041)*Loop2(90000)=93690000
My Thread's ID [13] (null)
Total=Loop1(50000)*Loop2(90000)=205032704
Create thread id= 14[index=14]
My Thread's ID [14] (null)
Total=Loop1(684)*Loop2(90000)=61560000
Create thread id= 15[index=15]
My Thread's ID [15] (null)
Total=Loop1(537)*Loop2(90000)=48330000

thread 9: weight=[93] -21510000 [386730000]
thread 9: weight=[93],[1535952075,1535952077]Time=2 secs
thread 15: weight=[93] -21420000 [387270000]
thread 15: weight=[93],[1535952075,1535952077]Time=2 secs
thread 3: weight=[78] -39780000 [442170000]
thread 3: weight=[78],[1535952075,1535952078]Time=3 secs
thread 14: weight=[73] -51840000 [514440000]
thread 14: weight=[73],[1535952075,1535952078]Time=3 secs
thread 0: weight=[53] -55350000 [526230000]
thread 0: weight=[53],[1535952075,1535952078]Time=3 secs
thread 0, status=4294953792
thread 5: weight=[63] -63450000 [510840000]
thread 5: weight=[63],[1535952075,1535952078]Time=3 secs
thread 8: weight=[58] -75780000 [611820000]
thread 8: weight=[58],[1535952075,1535952078]Time=3 secs
thread 10: weight=[58] -76050000 [612090000]
thread 10: weight=[58],[1535952075,1535952078]Time=3 secs
thread 1: weight=[54] -76050000 [557820000]
thread 1: weight=[54],[1535952075,1535952078]Time=3 secs
thread 1, status=4294953796
thread 12: weight=[48] -86760000 [676710000]
thread 12: weight=[48],[1535952075,1535952078]Time=3 secs
thread 4: weight=[42] -86670000 [716490000]
thread 4: weight=[42],[1535952075,1535952079]Time=4 secs
thread 6: weight=[31] -48780000 [792630000]
thread 6: weight=[31],[1535952075,1535952079]Time=4 secs
thread 7: weight=[15] 261000000 [1208520000]
thread 7: weight=[15],[1535952075,1535952081]Time=6 secs
thread 11: weight=[15] 261270000 [1208880000]
thread 11: weight=[15],[1535952075,1535952081]Time=6 secs
thread 2: weight=[5] 261180000 [1547460000]
thread 2: weight=[5],[1535952075,1535952084]Time=9 secs
thread 2, status=4294953800
thread 3, status=4294953804
thread 4, status=4294953808
thread 5, status=4294953812
thread 6, status=4294953816
thread 7, status=4294953820
thread 8, status=4294953824
thread 9, status=4294953828
thread 10, status=4294953832
thread 11, status=4294953836
thread 12, status=4294953840
thread 13: weight=[1] -433517296 [1113942704]
thread 13: weight=[1],[1535952075,1535952093]Time=18 secs
thread 13, status=4294953844
thread 14, status=4294953848
thread 15, status=4294953852
global_var=-433517296, [1113942704 - 1547460000]=-433517296
laikc@laikc-PC ~
$ ./tlock_wrr16
wrr[0]=24 wrr[1]=63 wrr[2]=41 wrr[3]=9 wrr[4]=44 wrr[5]=28 wrr[6]=43 wrr[7]=42 wrr[8]=7 wrr[9]=46 wrr[10]=4 wrr[11]=6 wrr[12]=47 wrr[13]=27 wrr[14]=83 wrr[15]=78
Create thread id= 0[index=0]
Create thread id= 1[index=1]
My Thread's ID [0] Hello 0
Total=Loop1(2083)Loop2(90000)=187470000
My Thread's ID [1] Hello 1
Create thread id= 2[index=2]
Total=Loop1(793)Loop2(90000)=71370000
My Thread's ID [2] Hello 2
Total=Loop1(1219)Loop2(90000)=109710000
Create thread id= 3[index=3]
My Thread's ID [3] Hello 3
Total=Loop1(5555)Loop2(90000)=499950000
Create thread id= 4[index=4]
My Thread's ID [4] *****Error
Why?
Total=Loop1(1136)*Loop2(90000)=102240000
Create thread id= 5[index=5]
My Thread's ID [5] (null)
Total=Loop1(1785)*Loop2(90000)=160650000
Create thread id= 6[index=6]
My Thread's ID [6] (null)
Total=Loop1(1162)*Loop2(90000)=104580000
Create thread id= 7[index=7]
My Thread's ID [7] (null)
Total=Loop1(1190)*Loop2(90000)=107100000
Create thread id= 8[index=8]
My Thread's ID [8] (null)
Total=Loop1(7142)*Loop2(90000)=642780000
Create thread id= 9[index=9]
My Thread's ID [9] (null)
Total=Loop1(1086)*Loop2(90000)=97740000
Create thread id= 10[index=10]
My Thread's ID [10] (null)
Total=Loop1(12500)*Loop2(90000)=1125000000
Create thread id= 11[index=11]
My Thread's ID [11] (null)
Total=Loop1(8333)*Loop2(90000)=749970000
Create thread id= 12[index=12]
My Thread's ID [12] (null)
Total=Loop1(1063)*Loop2(90000)=95670000
Create thread id= 13[index=13]
My Thread's ID [13] (null)
Total=Loop1(1851)*Loop2(90000)=166590000
Create thread id= 14[index=14]
My Thread's ID [14] (null)
Total=Loop1(602)*Loop2(90000)=54180000
Create thread id= 15[index=15]
My Thread's ID [15] (null)
Total=Loop1(641)*Loop2(90000)=57690000
thread 14: weight=[83] -10890000 [444870000]
thread 14: weight=[83],[1535952104,1535952107]Time=3 secs
thread 15: weight=[78] -7470000 [462150000]
thread 15: weight=[78],[1535952104,1535952107]Time=3 secs
thread 1: weight=[63] -7560000 [555750000]
thread 1: weight=[63],[1535952104,1535952107]Time=3 secs
thread 12: weight=[47] -32130000 [735300000]
thread 12: weight=[47],[1535952104,1535952108]Time=4 secs
thread 9: weight=[46] -31950000 [715410000]
thread 9: weight=[46],[1535952104,1535952108]Time=4 secs
thread 4: weight=[44] -36360000 [773820000]
thread 4: weight=[44],[1535952104,1535952108]Time=4 secs
thread 6: weight=[43] -36540000 [785880000]
thread 6: weight=[43],[1535952104,1535952108]Time=4 secs
thread 7: weight=[42] -33840000 [762120000]
thread 7: weight=[42],[1535952104,1535952108]Time=4 secs
thread 2: weight=[41] -34020000 [805950000]
thread 2: weight=[41],[1535952104,1535952108]Time=4 secs
thread 5: weight=[28] 17100000 [976140000]
thread 5: weight=[28],[1535952104,1535952109]Time=5 secs
thread 13: weight=[27] 17280000 [994500000]
thread 13: weight=[27],[1535952104,1535952110]Time=6 secs
thread 0: weight=[24] 7380000 [1006650000]
thread 0: weight=[24],[1535952104,1535952110]Time=6 secs
thread 0, status=4294953792
thread 1, status=4294953796
thread 2, status=4294953800
thread 3: weight=[9] 7380000 [1660860000]
thread 3: weight=[9],[1535952104,1535952113]Time=9 secs
thread 3, status=4294953804
thread 4, status=4294953808
thread 5, status=4294953812
thread 6, status=4294953816
thread 7, status=4294953820
thread 8: weight=[7] -135540000 [1939320000]
thread 8: weight=[7],[1535952104,1535952114]Time=10 secs
thread 8, status=4294953824
thread 9, status=4294953828
thread 11: weight=[6] -135630000 [1911060000]
thread 11: weight=[6],[1535952104,1535952115]Time=11 secs
thread 10: weight=[4] -510570000 [-1873337296]
thread 10: weight=[4],[1535952104,1535952116]Time=12 secs
thread 10, status=4294953832
thread 11, status=4294953836
thread 12, status=4294953840
thread 13, status=4294953844
thread 14, status=4294953848
thread 15, status=4294953852
global_var=-510570000, [1911060000 - -1873337296]=-510570000
laikc@laikc-PC ~
$ ./tlock_wrr16
wrr[0]=11 wrr[1]=10 wrr[2]=90 wrr[3]=66 wrr[4]=10 wrr[5]=90 wrr[6]=1 wrr[7]=80 wrr[8]=6 wrr[9]=68 wrr[10]=75 wrr[11]=23 wrr[12]=64 wrr[13]=97 wrr[14]=31 wrr[15]=65
Create thread id= 0[index=0]
My Thread's ID [0] Hello 0
Total=Loop1(4545)Loop2(90000)=409050000
Create thread id= 1[index=1]
My Thread's ID [1] Hello 1
Create thread id= 2[index=2]
Total=Loop1(5000)Loop2(90000)=450000000
My Thread's ID [2] Hello 2
Total=Loop1(555)Loop2(90000)=49950000
Create thread id= 3[index=3]
My Thread's ID [3] Hello 3
Total=Loop1(757)Loop2(90000)=68130000
Create thread id= 4[index=4]
My Thread's ID [4] *****Error
Why?
Total=Loop1(5000)*Loop2(90000)=450000000
Create thread id= 5[index=5]
My Thread's ID [5] (null)
Total=Loop1(555)*Loop2(90000)=49950000
Create thread id= 6[index=6]
My Thread's ID [6] (null)
Total=Loop1(50000)*Loop2(90000)=205032704
Create thread id= 7[index=7]
My Thread's ID [7] (null)
Total=Loop1(625)*Loop2(90000)=56250000
Create thread id= 8[index=8]
My Thread's ID [8] (null)
Total=Loop1(8333)*Loop2(90000)=749970000
Create thread id= 9[index=9]
My Thread's ID [9] (null)
Total=Loop1(735)*Loop2(90000)=66150000
Create thread id= 10[index=10]
My Thread's ID [10] (null)
Total=Loop1(666)*Loop2(90000)=59940000
Create thread id= 11[index=11]
My Thread's ID [11] (null)
Total=Loop1(2173)*Loop2(90000)=195570000
Create thread id= 12[index=12]
My Thread's ID [12] (null)
Total=Loop1(781)*Loop2(90000)=70290000
Create thread id= 13[index=13]
My Thread's ID [13] (null)
Total=Loop1(515)*Loop2(90000)=46350000
Create thread id= 14[index=14]
My Thread's ID [14] (null)
Total=Loop1(1612)*Loop2(90000)=145080000
Create thread id= 15[index=15]
My Thread's ID [15] (null)
Total=Loop1(769)*Loop2(90000)=69210000
thread 13: weight=[97] -9900000 [371340000]
thread 13: weight=[97],[1535952120,1535952122]Time=2 secs
thread 2: weight=[90] -13500000 [408330000]
thread 2: weight=[90],[1535952120,1535952122]Time=2 secs
thread 5: weight=[90] -13410000 [395550000]
thread 5: weight=[90],[1535952120,1535952122]Time=2 secs
thread 7: weight=[80] -19620000 [433710000]
thread 7: weight=[80],[1535952120,1535952122]Time=2 secs
thread 10: weight=[75] -27180000 [479520000]
thread 10: weight=[75],[1535952120,1535952123]Time=3 secs
thread 9: weight=[68] -33390000 [483390000]
thread 9: weight=[68],[1535952120,1535952123]Time=3 secs
thread 3: weight=[66] -36990000 [490860000]
thread 3: weight=[66],[1535952120,1535952123]Time=3 secs
thread 15: weight=[65] -40950000 [494730000]
thread 15: weight=[65],[1535952120,1535952123]Time=3 secs
thread 12: weight=[64] -45090000 [541890000]
thread 12: weight=[64],[1535952120,1535952123]Time=3 secs
thread 14: weight=[31] -269460000 [915930000]
thread 14: weight=[31],[1535952120,1535952124]Time=4 secs
thread 11: weight=[23] -370350000 [747360000]
thread 11: weight=[23],[1535952120,1535952125]Time=5 secs
thread 0: weight=[11] -980370000 [1931040000]
thread 0: weight=[11],[1535952120,1535952128]Time=8 secs
thread 0, status=4294953792
thread 1: weight=[10] -1082070000 [1001610000]
thread 1: weight=[10],[1535952120,1535952128]Time=8 secs
thread 1, status=4294953796
thread 2, status=4294953800
thread 3, status=4294953804
thread 4: weight=[10] -1082520000 [2084130000]
thread 4: weight=[10],[1535952120,1535952128]Time=8 secs
thread 4, status=4294953808
thread 5, status=4294953812
thread 8: weight=[6] -1682640000 [-1610717296]
thread 8: weight=[6],[1535952120,1535952130]Time=10 secs
thread 6: weight=[1] -1137702704 [2139312704]
thread 6: weight=[1],[1535952120,1535952140]Time=20 secs
thread 6, status=4294953816
thread 7, status=4294953820
thread 8, status=4294953824
thread 9, status=4294953828
thread 10, status=4294953832
thread 11, status=4294953836
thread 12, status=4294953840
thread 13, status=4294953844
thread 14, status=4294953848
thread 15, status=4294953852
global_var=-1137702704, [1001610000 - 2139312704]=-1137702704
laikc@laikc-PC ~
$


Random Sleep
注意 Time= 的關係!!!
現象與 WRR 不同

前面 WRR 是調整 thread 的執行迴圈數: 消耗CPU 量
這裏 是usleep, 空出時間給別的 process, thread,等使用


/* Simple Random Sleep Example. Copyright 2018 GPL Author WhoAmI Random random_us random_us[0]....random_us[MAXTHREADS-1] */ #include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> #include <stdlib.h> //gcc tlock_usleep.c -Wall -o tlock_usleep -lpthread //int usleep(useconds_t usec); #define MAXTHREADS 4 #define PTHREADID 0 #define LIMITMAX 30000 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t demomutex2=PTHREAD_MUTEX_INITIALIZER; static int random_us[MAXTHREADS+1]; static int id_sum[2]; static int Loop1=500; void *HelloUS(void *pthreadid) { int *idp, id; int loop1,loop2; int Loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; Loop2=50000; printf("Total=Loop1(%d)*Loop2(%d)=%ld\n",Loop1,Loop2,Loop1*Loop2); time(&t0); for(loop1=0;loop1<Loop1;loop1++) { pthread_mutex_lock(&demomutex); usleep(random_us[id-PTHREADID]); for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0){ global_var--; id_sum[0]++; } else { global_var++; id_sum[1]++; } } pthread_mutex_unlock(&demomutex); } printf(">>>thread %d: usleep=[%d] usec %d [%d]\n",id-PTHREADID,random_us[id-PTHREADID],global_var,id_sum[(id-PTHREADID)%2]); time(&t1); printf("thread %d: usleep=[%d] usec,[%ld,%ld]Time=%ld secs\n",id-PTHREADID,random_us[id-PTHREADID],t0,t1,t1-t0); pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; unsigned int seed; // you can use pthread_mutex_init(demomutex,NULL). seed=time(NULL); srandom(seed); for(i=0; i<MAXTHREADS;i++){ random_us[i]= random()%20000+100; //random us printf("random_us[%d]=%d ",i,random_us[i]); } printf("\n"); global_var=0; id_sum[0]=0; id_sum[1]=0; if(argc==2){ Loop1=atoi(argv[1]); } printf("Loop1=%d\n",Loop1); for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, HelloUS, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } // pthread_mutex_destroy(&demomutex); printf("global_var=%d, [%d - %d]=%d\n",global_var,id_sum[1],id_sum[0],id_sum[1]-id_sum[0]); //sleep(10); }

laikc@laikc-PC ~
$ ./tlock_usleep 500
random_us[0]=3219 random_us[1]=734 random_us[2]=15010 random_us[3]=2978
Loop1=500
Create thread id= 0[index=0]
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 1[index=1]
Create thread id= 2[index=2]
Total=Loop1(500)*Loop2(50000)=25000000
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 3[index=3]
Total=Loop1(500)*Loop2(50000)=25000000

thread 0: usleep=[3219] usec -50000 [49950000]
thread 0: usleep=[3219] usec,[1535962050,1535962081]Time=31 secs
thread 0, status=4294953936
thread 1: usleep=[734] usec 0 [49950000]
thread 1: usleep=[734] usec,[1535962050,1535962081]Time=31 secs
thread 1, status=4294953940
thread 2: usleep=[15010] usec -50000 [50000000]
thread 2: usleep=[15010] usec,[1535962050,1535962081]Time=31 secs
thread 2, status=4294953944
thread 3: usleep=[2978] usec 0 [50000000]
thread 3: usleep=[2978] usec,[1535962050,1535962081]Time=31 secs
thread 3, status=4294953948
global_var=0, [50000000 - 50000000]=0
laikc@laikc-PC ~
$ ./tlock_usleep 100
random_us[0]=1642 random_us[1]=783 random_us[2]=10970 random_us[3]=8736
Loop1=100
Create thread id= 0[index=0]
Create thread id= 1[index=1]
Total=Loop1(100)*Loop2(50000)=5000000
Create thread id= 2[index=2]
Total=Loop1(100)*Loop2(50000)=5000000
Total=Loop1(100)*Loop2(50000)=5000000
Create thread id= 3[index=3]
Total=Loop1(100)*Loop2(50000)=5000000
thread 0: usleep=[1642] usec -50000 [9950000]
thread 0: usleep=[1642] usec,[1535962109,1535962115]Time=6 secs
thread 0, status=4294953936
thread 1: usleep=[783] usec 0 [9950000]
thread 1: usleep=[783] usec,[1535962109,1535962115]Time=6 secs
thread 1, status=4294953940
thread 2: usleep=[10970] usec -50000 [10000000]
thread 2: usleep=[10970] usec,[1535962109,1535962115]Time=6 secs
thread 2, status=4294953944
thread 3: usleep=[8736] usec 0 [10000000]
thread 3: usleep=[8736] usec,[1535962109,1535962115]Time=6 secs
thread 3, status=4294953948
global_var=0, [10000000 - 10000000]=0
laikc@laikc-PC ~
$ ./tlock_usleep 300
random_us[0]=19606 random_us[1]=19642 random_us[2]=4940 random_us[3]=245
Loop1=300
Create thread id= 0[index=0]
Total=Loop1(300)*Loop2(50000)=15000000
Create thread id= 1[index=1]
Create thread id= 2[index=2]
Total=Loop1(300)*Loop2(50000)=15000000
Total=Loop1(300)*Loop2(50000)=15000000
Create thread id= 3[index=3]
Total=Loop1(300)*Loop2(50000)=15000000
thread 0: usleep=[19606] usec -50000 [29950000]
thread 0: usleep=[19606] usec,[1535962123,1535962151]Time=28 secs
thread 0, status=4294953936
thread 1: usleep=[19642] usec 0 [29950000]
thread 1: usleep=[19642] usec,[1535962123,1535962151]Time=28 secs
thread 1, status=4294953940
thread 2: usleep=[4940] usec -50000 [30000000]
thread 2: usleep=[4940] usec,[1535962123,1535962151]Time=28 secs
thread 2, status=4294953944
thread 3: usleep=[245] usec 0 [30000000]
thread 3: usleep=[245] usec,[1535962123,1535962151]Time=28 secs
thread 3, status=4294953948
global_var=0, [30000000 - 30000000]=0
laikc@laikc-PC ~
$ ./tlock_usleep 500
random_us[0]=13829 random_us[1]=4130 random_us[2]=10897 random_us[3]=3222
Loop1=500
Create thread id= 0[index=0]
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 1[index=1]
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 2[index=2]
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 3[index=3]
Total=Loop1(500)*Loop2(50000)=25000000
thread 0: usleep=[13829] usec -50000 [49950000]
thread 0: usleep=[13829] usec,[1535962157,1535962188]Time=31 secs
thread 0, status=4294953936
thread 1: usleep=[4130] usec 0 [49950000]
thread 1: usleep=[4130] usec,[1535962157,1535962188]Time=31 secs
thread 1, status=4294953940
thread 2: usleep=[10897] usec -50000 [50000000]
thread 2: usleep=[10897] usec,[1535962157,1535962188]Time=31 secs
thread 2, status=4294953944
thread 3: usleep=[3222] usec 0 [50000000]
thread 3: usleep=[3222] usec,[1535962157,1535962188]Time=31 secs
thread 3, status=4294953948
global_var=0, [50000000 - 50000000]=0
laikc@laikc-PC ~
$ ./tlock_usleep 600
random_us[0]=15052 random_us[1]=18283 random_us[2]=10044 random_us[3]=16940
Loop1=600
Create thread id= 0[index=0]
Total=Loop1(600)*Loop2(50000)=30000000
Create thread id= 1[index=1]
Create thread id= 2[index=2]
Total=Loop1(600)*Loop2(50000)=30000000
Total=Loop1(600)*Loop2(50000)=30000000
Create thread id= 3[index=3]
Total=Loop1(600)*Loop2(50000)=30000000
thread 0: usleep=[15052] usec -50000 [59950000]
thread 0: usleep=[15052] usec,[1535962196,1535962252]Time=56 secs
thread 0, status=4294953936
thread 1: usleep=[18283] usec 0 [59950000]
thread 1: usleep=[18283] usec,[1535962196,1535962252]Time=56 secs
thread 1, status=4294953940
thread 2: usleep=[10044] usec -50000 [60000000]
thread 2: usleep=[10044] usec,[1535962196,1535962252]Time=56 secs
thread 2, status=4294953944
thread 3: usleep=[16940] usec 0 [60000000]
thread 3: usleep=[16940] usec,[1535962196,1535962252]Time=56 secs
thread 3, status=4294953948
global_var=0, [60000000 - 60000000]=0
laikc@laikc-PC ~
$ ./tlock_usleep 1000
random_us[0]=15807 random_us[1]=10134 random_us[2]=11820 random_us[3]=12044
Loop1=1000
Create thread id= 0[index=0]
Total=Loop1(1000)*Loop2(50000)=50000000
Create thread id= 1[index=1]
Create thread id= 2[index=2]
Total=Loop1(1000)*Loop2(50000)=50000000
Total=Loop1(1000)*Loop2(50000)=50000000
Create thread id= 3[index=3]
Total=Loop1(1000)*Loop2(50000)=50000000
thread 0: usleep=[15807] usec -50000 [99950000]
thread 0: usleep=[15807] usec,[1535962260,1535962337]Time=77 secs
thread 0, status=4294953936
thread 1: usleep=[10134] usec 0 [99950000]
thread 1: usleep=[10134] usec,[1535962260,1535962337]Time=77 secs
thread 1, status=4294953940
thread 2: usleep=[11820] usec -50000 [100000000]
thread 2: usleep=[11820] usec,[1535962260,1535962337]Time=77 secs
thread 2, status=4294953944
thread 3: usleep=[12044] usec 0 [100000000]
thread 3: usleep=[12044] usec,[1535962260,1535962337]Time=77 secs
thread 3, status=4294953948
global_var=0, [100000000 - 100000000]=0
laikc@laikc-PC ~
$
laikc@laikc-PC ~
$ ./tlock_usleep 500
random_us[0]=916 random_us[1]=11910 random_us[2]=8703 random_us[3]=2016
Loop1=500
Create thread id= 0[index=0]
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 1[index=1]
Create thread id= 2[index=2]
Total=Loop1(500)*Loop2(50000)=25000000
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 3[index=3]
Total=Loop1(500)*Loop2(50000)=25000000
thread 0: usleep=[916] usec -50000 [49950000]
thread 0: usleep=[916] usec,[1535962597,1535962624]Time=27 secs
thread 0, status=4294953936
thread 1: usleep=[11910] usec 0 [49950000]
thread 1: usleep=[11910] usec,[1535962597,1535962624]Time=27 secs
thread 1, status=4294953940
thread 2: usleep=[8703] usec -50000 [50000000]
thread 2: usleep=[8703] usec,[1535962597,1535962624]Time=27 secs
thread 2, status=4294953944
thread 3: usleep=[2016] usec 0 [50000000]
thread 3: usleep=[2016] usec,[1535962597,1535962624]Time=27 secs
thread 3, status=4294953948
global_var=0, [50000000 - 50000000]=0
laikc@laikc-PC ~
$ ./tlock_usleep 500
random_us[0]=12732 random_us[1]=17639 random_us[2]=11313 random_us[3]=13258
Loop1=500
Create thread id= 0[index=0]
Create thread id= 1[index=1]
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 2[index=2]
Total=Loop1(500)*Loop2(50000)=25000000
Total=Loop1(500)*Loop2(50000)=25000000
Create thread id= 3[index=3]
Total=Loop1(500)*Loop2(50000)=25000000
thread 0: usleep=[12732] usec -50000 [49950000]
thread 0: usleep=[12732] usec,[1535962649,1535962682]Time=33 secs
thread 0, status=4294953936
thread 1: usleep=[17639] usec 0 [49950000]
thread 1: usleep=[17639] usec,[1535962649,1535962682]Time=33 secs
thread 1, status=4294953940
thread 2: usleep=[11313] usec -50000 [50000000]
thread 2: usleep=[11313] usec,[1535962649,1535962682]Time=33 secs
thread 2, status=4294953944
thread 3: usleep=[13258] usec 0 [50000000]
thread 3: usleep=[13258] usec,[1535962649,1535962682]Time=33 secs
thread 3, status=4294953948
global_var=0, [50000000 - 50000000]=0
laikc@laikc-PC ~
$


為方便簡單觀察


/* Simple Random Sleep Example. Copyright 2018 GPL Author WhoAmI Random random_us random_us[0]....random_us[MAXTHREADS-1] */ #include <stdio.h> #include <pthread.h> #include <time.h> #include <string.h> #include <stdlib.h> #include<sys/time.h> //gcc tlock_usleep_all.c -Wall -o tlock_usleep_all -lpthread //int usleep(useconds_t usec); #define MAXTHREADS 4 #define PTHREADID 0 #define LIMITMAX 30000 int global_var=0; static pthread_mutex_t demomutex=PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t demomutex2=PTHREAD_MUTEX_INITIALIZER; static int random_us[MAXTHREADS+1]; static int id_sum[2]; static int Loop1=500; static int Loop2=50000; static int silence=0; void *HelloUS(void *pthreadid) { int *idp, id; int loop1,loop2; time_t t0,t1; // sleep(1); idp = (int *) pthreadid; id = *idp; time(&t0); for(loop1=0;loop1<Loop1;loop1++) { if(usleep(random_us[id-PTHREADID])<0){ perror("usleep"); } pthread_mutex_lock(&demomutex); for(loop2=0;loop2<Loop2;loop2++){ if(id%2==0){ global_var--; id_sum[0]++; } else { global_var++; id_sum[1]++; } } pthread_mutex_unlock(&demomutex); } time(&t1); if(!silence)printf(">>>thread %d: usleep=[%d] usec global_var=%d [%d]\n",id-PTHREADID,random_us[id-PTHREADID],global_var,id_sum[(id-PTHREADID)%2]); if(!silence)printf("thread %d: usleep=[%d] usec,[%ld,%ld]Time=%ld secs\n",id-PTHREADID,random_us[id-PTHREADID],t0,t1,t1-t0); pthread_exit((void*) pthreadid); } int main(int argc, char *argv[]) { pthread_t child[MAXTHREADS]; int id[MAXTHREADS]; int i; int s; void *status; unsigned int seed; time_t t0,t1; unsigned int us; int total; unsigned long diff; struct timeval start; struct timeval end; // you can use pthread_mutex_init(demomutex,NULL). for(i=0;i<argc;i++){ if(strcmp(argv[i],"-s")==0)silence=!0; if(strcmp(argv[i],"-l")==0)Loop1=atoi(argv[++i]); } if(!silence)printf("Loop1=%d\n",Loop1); seed=time(NULL); srandom(seed); us=0; for(i=0; i<MAXTHREADS;i++){ random_us[i]= random()%20000+100; //random us if(!silence) printf("random_us[%d]=%d ",i,random_us[i]); if(random_us[i]>us)us=random_us[i]; //find the maximum } if(!silence)printf("\nus=%d\n",us); global_var=0; id_sum[0]=0; id_sum[1]=0; gettimeofday(&start,NULL); time(&t0); for(i=0;i<MAXTHREADS;i++) { id[i]=i+PTHREADID; // printf("Create thread id= %d[index=%d]\n", id[i],i); pthread_create(&child[i], NULL, HelloUS, (void *) &id[i]); } /** Wait for all threads to finish **/ for (i = 0; i < MAXTHREADS; i++) { s=pthread_join(child[i], &status); if(s==0) { if(!silence)printf("thread %d, status=%ld\n",i,(long)status); } else { perror("pthread"); } } time(&t1); gettimeofday(&end,NULL); diff = (1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec)/1000; //msecs // pthread_mutex_destroy(&demomutex); total=((us)*(Loop1))/1000; if(!silence)printf("global_var=%d, [%d - %d]=%d,max us=%d usecs [sleep ~ %d msecs],[%ld,%ld]=%ld msecs\n",global_var,id_sum[1],id_sum[0],id_sum[1]-id_sum[0],us,total,t0,t1,diff); else printf("global_var=%d, max us=%d usecs,loop=%d, sleep ~ %d msecs, %ld msecs\n",global_var,us,Loop1,total,diff); //sleep(10); }

cygwin 下


laikc@laikc-PC ~
$ ./tlock_usleep_all -s -l 100
global_var=0, max us=17279 usecs,loop=100, sleep ~ 1727 msecs, 1815 msecs
laikc@laikc-PC ~
$ ./tlock_usleep_all -s -l 100
global_var=0, max us=18435 usecs,loop=100, sleep ~ 1843 msecs, 1909 msecs
laikc@laikc-PC ~
$ ./tlock_usleep_all -s -l 300
global_var=0, max us=12104 usecs,loop=300, sleep ~ 3631 msecs, 3923 msecs
laikc@laikc-PC ~
$ ./tlock_usleep_all -s -l 300
global_var=0, max us=7850 usecs,loop=300, sleep ~ 2355 msecs, 2415 msecs
laikc@laikc-PC ~
$ ./tlock_usleep_all -s -l 300
global_var=0, max us=19117 usecs,loop=300, sleep ~ 5735 msecs, 6032 msecs
laikc@laikc-PC ~
$ ./tlock_usleep_all -s -l 500
global_var=0, max us=19711 usecs,loop=500, sleep ~ 9855 msecs, 14914 msecs
laikc@laikc-PC ~
$ ./tlock_usleep_all -s -l 500
global_var=0, max us=13589 usecs,loop=500, sleep ~ 6794 msecs, 7912 msecs
laikc@laikc-PC ~
$ ./tlock_usleep_all -s -l 1000
global_var=0, max us=15991 usecs,loop=1000, sleep ~ 15991 msecs, 28782 msecs
laikc@laikc-PC ~
$