# 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 的可能比較 ![](https://i.imgur.com/iE4qtLr.jpg) <center>Fig. 1</center> ![](https://i.imgur.com/IMLByl9.jpg) ![](https://i.imgur.com/DTEUWSg.jpg) <center>Fig. 2</center> ![](https://i.imgur.com/CNrNqkg.jpg) ![](https://i.imgur.com/ggICWU5.jpg) <center>Fig. 3,4</center> :::info **Remark.** $I_1, I_2$ idle time Assume $N_1=N_2$, $N_{1-0}=N_{2-0}$ and $T_1+I_1=T_2+I_2$. CASE 1: $N_{1-0}(I_{1-0}+ N_1*(T_1+I_1))=N_{2-0}(I_{1-0})+N_{1-0}N_1T_1+N_{1-0}N_1I_1$ CASE 2: $N_{2-0}(I_{2-0}+ N_2*(T_2+I_2))=N_{1-0}(I_{1-0})+N_{1-0}N_2T_2+N_{1-0}N_2I_2$ If $I_2 > I_1$ then $N_{1-0}N_1(I_2-I_1)$, i.e., **CASE 2** is better. ::: ![](https://i.imgur.com/SurfQVW.jpg) ```c= /* 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 ```c= 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%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("[%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%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("[%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,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, 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 ***************************** ```c= #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 的位置! *************************************** ```c= #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 *************************************** ```c= #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 的影響 ****************************** ```c= #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? *************************************** ```c= #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 ****************************** ```c= 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? ************************************** ```c= 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? **************************************** ```c= 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 離開的順序!!!! ***************************************** ```c= 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 就會結束!!! *********************************************** ```c= #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); } ``` ****************************** :::info 以下是 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. ******************** =============================================== ```c= /* 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 ---------------------------------------------------------------------- :::info 以下是將#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,...等使用 ****************************************************** ```c= /* 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 ~ $ ********************************************** 為方便簡單觀察 ********************************************* ```c= /* 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 ~ $ *********************************************