C指針原理(47)-C應用技巧(2)
BOSS線程的主要任務是創建worker線程,將工作線程放入隊列中,當有工作可處理時,喚醒 工作線程。
/ Create a new thread, starting with execution of START-ROUTINE getting passed ARG. Creation attributed come from ATTR. The new handle is stored in NEWTHREAD. /
extern int pthread_create (pthread_t restrict
const pthread_attr_t *restrict attr,
void (start_routine) (void ),
void restrict arg) THROW nonnull ((1, 3));
/ Obtain the identifier of the current thread. /
extern pthread_t pthread_self (void) THROW attribute ((const));
//返回調用該函數的當前線程的pthread_t結構指針
/ Make calling thread wait for termination of the thread TH. The
is not NULL.
This function is a cancellation point and therefore not marked with
THROW. */
extern int pthread_join (pthread_t th, void **__thread_return);//thread_return退出狀態
//pthread_join導致調用線程掛起它的執行,直到目標線程的結束。
main.c
#include <pthread.h> #include <stdio.h> ?//2個工作線程,分別是累加和累乘 void *mycompadd(void *xx){//參數必須為void *,然後進行強制類型轉換 ? int sum=0;? ? int *x=(int *)(xx); ? for (int i=0;i<*x;i++){ ? ? sum+=i; ? } ? printf("add%d\n",sum); ? ? } void ?*mycompchen(void *xx){//參數必須為void *,然後進行強制類型轉換 ? int sum=1;? ? int *x=(int *)(xx); ? for (int i=1;i<=*x;i++){ ? ? sum*=i; ? ? } ? printf("chen%d\n",sum); ?? } ? ? int main(){ ? //main為boss線程, ? pthread_t threada,threadb; ? //創建worker線程,並執行線程 ? int n=3; ? pthread_create(&threada,NULL,mycompadd,&n);//線程,線程屬性,函數,參數。如果有多個參數,必須傳結構指針 ? pthread_create(&threadb,NULL,mycompchen,&n);//線程,線程屬性,函數,參數 ? //wait worker線程,並合並到BOSS線程來 ? pthread_join(threada,NULL); ? pthread_join(threadb,NULL); ? return(0); }
執行效果:
deepfuture@deepfuture-laptop:~/mytest$ gcc -lpthread -std=c99 -o main main.c
deepfuture@deepfuture-laptop:~/mytest$ ./main
add3
chen6
deepfuture@deepfuture-laptop:~/mytest$?
C-多線程-取消及取消點
?
線程取消
編譯:
gcc -std=c99 -lpthread -o main main.c
?
deepfuture@deepfuture-laptop:~/mytest$ ./main
10000print:250
10000print:500
10000print:750
1add1
1chen1
thread0 已經取消!
thread1 已經取消!
2chen2
3chen6
4chen24
5chen120
6chen720
7chen5040
8chen40320
9chen362880
10chen3628800
11chen39916800
12chen479001600
13chen1932053504
14chen1278945280
15chen2004310016
16chen2004189184
17chen-288522240
18chen-898433024
19chen109641728
20chen-2102132736
21chen-1195114496
22chen-522715136
23chen862453760
24chen-775946240
25chen2076180480
thread2 不能被取消!deepfuture@deepfuture-laptop:~/mytest$?
br/>deepfuture@deepfuture-laptop:~/mytest$?
C代碼 ?
#include <pthread.h> ?
#include <stdio.h> ?
??
#define MAXTHREADS 3 ??
??
void *mycompprint(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate);//設置線程是可以中止的。 ?
? pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,&oldtype);//設置線程推遲中止,PTHREAD_CANCEL_DEFERRED為默認值。 ?
? int *x=(int *)(xx); ? ?
? for (int i=1;i<*x;i++){ ?
? ? if ((i%250)==0) {//如果i為250的倍數則取消 ?
? ? ?printf("%dprint:%d\n",*x,i); ? ? ??
? ? ?pthread_testcancel();//pthread_testcancel()檢測是否需要取消,設置取消點,如果有掛起的取消請求,則在此處中止本線程 ?
? ? } ? ? ?
? } ?
} ?
??
??
void *mycompadd(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate);//設置線程是可以中止的。 ?
? pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldtype);//設置線程線程立即中止,PTHREAD_CANCEL_ASYNCHRONOUS表示線程立即終止。 ?
? int sum=0; ??
? int *x=(int *)(xx); ?
? int y; ?
? for (int i=1;i<=*x;i++){ ?
? ? sum+=i; ??
? ? printf("%dadd%d\n",i,sum); ? ? ?
? } ?
??
} ?
??
??
??
??
void ?*mycompchen(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
? pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,&oldstate);//設置線程不能中止的。 ? ?
? int sum=1; ??
? int *x=(int *)(xx); ?
? for (int i=1;i<=*x;i++){ ?
? ? sum*=i; ? ? ?
? ? printf("%dchen%d\n",i,sum); ? ? ? ?
? } ?
??
} ?
??
??
int main(){ ?
? //線程分離後,不能再合並 ?
? //main為boss線程, ?
? ?pthread_t threads[MAXTHREADS];//創建線程池 ?
? void *status; ?
? //創建worker線程,並執行線程 ?
? int n1=25; ?
? int n2=10000; ?
? ??
??
? pthread_create(&(threads[0]),NULL,mycompprint,&n2); ? ??
? pthread_create(&(threads[1]),NULL,mycompadd,&n1); ??
? pthread_create(&(threads[2]),NULL,mycompchen,&n1); ??
? ??
? for (int i=0;i<MAXTHREADS;i++){ ?
? ? ? ?pthread_cancel(threads[i]); ? ?
? } ? ?
??
? for (int i=0;i<MAXTHREADS;i++){ ?
? ? ? ?pthread_join(threads[i],&status); ?//wait worker線程,並合並到BOSS線程來 ?
? ? ? ?if (status==PTHREAD_CANCELED){ ?
? ? ? ? printf("thread%d 已經取消!\n",i); ?
? ? ? ?} ?
? ? ? ?else{ ?
? ? ? ? printf("thread%d 不能被取消!\n",i); ?
? ? ? ?} ? ? ?
? ? ? ? ?
? } ??
? return(0); ?
} ?
?
c-多線程-中止前清理
gcc -lpthread -std=c99 -o main main.c
deepfuture@deepfuture-laptop:~/mytest$ ./main
1chen1
2chen2
3chen6
4chen24
5chen120
6chen720
7chen5040
8chen40320
9chen362880
10chen3628800
11chen39916800
12chen479001600
13chen1932053504
14chen1278945280
15chen2004310016
16chen2004189184
17chen-288522240
18chen-898433024
19chen109641728
20chen-2102132736
21chen-1195114496
22chen-522715136
23chen862453760
24chen-775946240
25chen2076180480
1add1
10000print:250
clear:10000
thread0 已經取消!
thread1 已經取消!
thread2 不能被取消!
?
C代碼 ?
#include <pthread.h> ?
#include <stdio.h> ?
??
#define MAXTHREADS 3 ??
void *myclear(void *x){ ?
? ?printf("clear:%d\n",*((int*)x)); ?
} ?
void *mycompprint(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate);//設置線程是可以中止的。 ?
? pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,&oldtype);//設置線程推遲中止,PTHREAD_CANCEL_DEFERRED為默認值。 ?
? int *x=(int *)(xx); ? ?
? void *xxx=(void *)x; ?
? pthread_cleanup_push(myclear,xxx);//壓入線程清理堆棧,堆棧包含指向取消過程中執行例程的指針,即中止前執行一個清理。myclear為例程名,x為傳給例程的參數 ?
? for (int i=1;i<*x;i++){ ?
? ? if ((i%250)==0) {//如果i為250的倍數則取消 ?
? ? ?printf("%dprint:%d\n",*x,i); ? ? ??
? ? ?pthread_testcancel();//pthread_testcancel()檢測是否需要取消,設置取消點,如果有掛起的取消請求,則在此處中止本線程 ?
? ? } ? ? ?
? } ?
? pthread_cleanup_pop(0); //從調用線程清理堆棧的頂部移走清理函數指針,但並不執行它,pthread_testcancel()檢測不到取消請求,表示目前不需要取消,所以移走它。pthread_cleanup_pop(1)移走並執行它,即使並沒有中止線程; ??
} ?
??
??
void *mycompadd(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate);//設置線程是可以中止的。 ?
? pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&oldtype);//設置線程線程立即中止,PTHREAD_CANCEL_ASYNCHRONOUS表示線程立即終止。 ?
? int sum=0; ??
? int *x=(int *)(xx); ?
? int y; ?
? for (int i=1;i<=*x;i++){ ?
? ? sum+=i; ??
? ? printf("%dadd%d\n",i,sum); ? ? ?
? } ?
??
} ?
??
??
??
??
void ?*mycompchen(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
? pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,&oldstate);//設置線程不能中止的。 ? ?
? int sum=1; ??
? int *x=(int *)(xx); ?
? for (int i=1;i<=*x;i++){ ?
? ? sum*=i; ? ? ?
? ? printf("%dchen%d\n",i,sum); ? ? ? ?
? } ?
??
} ?
??
??
int main(){ ?
? //線程分離後,不能再合並 ?
? //main為boss線程, ?
? ?pthread_t threads[MAXTHREADS];//創建線程池 ?
? void *status; ?
? //創建worker線程,並執行線程 ?
? int n1=25; ?
? int n2=10000; ?
? ??
??
? pthread_create(&(threads[0]),NULL,mycompprint,&n2); ? ??
? pthread_create(&(threads[1]),NULL,mycompadd,&n1); ??
? pthread_create(&(threads[2]),NULL,mycompchen,&n1); ??
? ??
? for (int i=0;i<MAXTHREADS;i++){ ?
? ? ? ?pthread_cancel(threads[i]); ? ?
? } ? ?
??
? for (int i=0;i<MAXTHREADS;i++){ ?
? ? ? ?pthread_join(threads[i],&status); ?//wait worker線程,並合並到BOSS線程來 ?
? ? ? ?if (status==PTHREAD_CANCELED){ ?
? ? ? ? printf("thread%d 已經取消!\n",i); ?
? ? ? ?} ?
? ? ? ?else{ ?
? ? ? ? printf("thread%d 不能被取消!\n",i); ?
? ? ? ?} ? ? ?
? ? ? ? ?
? } ??
? return(0); ?
} ?
?linux-線程優先級
C代碼 ?
#include <pthread.h> ?
#include <stdio.h> ?
??
#define MAXTHREADS 3 ??
void *myclear(void *x){ ?
? ?printf("clear:%d\n",*((int*)x)); ?
} ?
void *mycompprint(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate);//設置線程是可以中止的。 ?
? pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,&oldtype);//設置線程推遲中止,PTHREAD_CANCEL_DEFERRED為默認值。 ?
? int *x=(int *)(xx); ? ?
? void *xxx=(void *)x; ?
? pthread_cleanup_push(myclear,xxx);//壓入線程清理堆棧,堆棧包含指向取消過程中執行例程的指針,即中止前執行一個清理。myclear為例程名,x為傳給例程的參數 ?
? for (int i=1;i<*x;i++){ ?
? ? if ((i%60)==0) {//如果i為250的倍數則取消 ?
? ? ?printf("%dprint:%d\n",*x,i); ? ? ??
? ? ?pthread_testcancel();//pthread_testcancel()檢測是否需要取消,設置取消點,如果有掛起的取消請求,則在此處中止本線程 ?
? ? } ? ? ?
? } ?
? pthread_cleanup_pop(0); //從調用線程清理堆棧的頂部移走清理函數指針,但並不執行它,pthread_testcancel()檢測不到取消請求,表示目前不需要取消,所以移走它。pthread_cleanup_pop(1)移走並執行它,即使並沒有中止線程; ??
} ?
??
??
void *mycompadd(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
? int sum=0; ??
? int *x=(int *)(xx); ?
? int y; ?
? pthread_attr_t attr1; ?
? pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,&oldstate);//設置線程不能中止的。 ? ?
? for (int i=1;i<=*x;i++){ ?
? ? sum+=i; ??
? ? printf("%dadd%d\n",i,sum); ? ? ?
? } ?
} ?
??
??
??
??
void ?*mycompchen(void *xx){//參數必須為void *,然後進行強制類型轉換 ?
? int oldstate,oldtype; ? ?
??
? size_t size; ? ?
? void *addr; ?
? int priority; ? ?
? pthread_attr_t attr1; ?
? struct sched_param param; ?
? ??
? pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,&oldstate);//設置線程不能中止的。 ?
? ? ?
? pthread_getattr_np(pthread_self(),&attr1);//獲取線程屬性。 ?
? ? ?
? pthread_attr_getstack(&attr1,&addr,&size);//線程屬性,地址,大小 ?
? param.sched_priority=sched_get_priority_min(SCHED_RR);//SCHED_RR策略的sched_get_priority_min最小優先值 ?
? pthread_setschedparam(pthread_self(),SCHED_RR,¶m);//動態設置調度策略 ?
//pthread_setschedprio(pthread_self(),sched_get_priority_min(SCHED_RR)); ?//另一種動態設置調度優先級的方法 ?
??
? printf("size:%d\n",size); //輸出線程堆棧大小 ? ??
??
??
? int sum=1; ??
? int *x=(int *)(xx); ?
? for (int i=1;i<=*x;i++){ ?
? ? sum*=i; ? ? ?
? ? printf("%dchen%d\n",i,sum); ? ? ? ?
? } ?
??
} ?
??
??
int main(){ ?
? //線程分離後,不能再合並 ?
? //main為boss線程, ?
? pthread_t threads[MAXTHREADS];//創建線程池 ?
? void *status; ?
? pthread_attr_t attr; ?
? //創建worker線程,並執行線程 ?
? int n1=25; ?
? int n2=10000; ?
? int priority; ? ?
? struct sched_param param; ?
? //靜態設置線程threads[1]調度及相關屬性,優先值越小,優先級越高 ? ? ? ?
? pthread_attr_init(&attr); ?
? priority=sched_get_priority_max(SCHED_RR);//SCHED_RR策略的sched_get_priority_max最大優先值 ?
//SCHED_RR輪詢調度,SCHED_FIFO先進先出,執行線程直到完成,SCHED_OTHER其他調度。sched_get_prority_max、sched_get_prority_min取得調度策略的最大優先值、最小優先值 ?
? param.sched_priority=priority;//設置param的優先級成員 ?
??
? pthread_attr_setschedparam(&attr,¶m);//通過param設置優先級 ?
? ??
??
? pthread_attr_setinheritsched(&attr,PTHREAD_EXPLICIT_SCHED);//PTHREAD_EXPLICIT_SCHED設置調度屬性為屬性對象的調度屬性,THREAD_INHERIT_EXPLICIT_SCHED為繼承調度屬性 ? ??
? pthread_create(&(threads[0]),NULL,mycompprint,&n2); ? ??
? pthread_create(&(threads[1]),&attr,mycompadd,&n1); ? ??
? pthread_create(&(threads[2]),NULL,mycompchen,&n1); \ ?
? ?
? for (int i=0;i<MAXTHREADS;i++){ ?
? ? ? ?pthread_cancel(threads[i]); ? ?
? } ??
? ?sleep(1); ??
? for (int i=0;i<MAXTHREADS;i++){ ?
pthread_join(threads[i],&status); ?//wait worker線程,並合並到BOSS線程來 ?
? ? ? ?if (status==PTHREAD_CANCELED){ ?
? ? ? ? printf("thread%d 已經取消!\n",i); ?
? ? ? ?} ?
? ? ? ?else{ ?
? ? ? ? printf("thread%d 不能被取消!\n",i); ?
? ? ? ?} ? ? ?
? ? ? ? ?
? } ??
? return(0); ?
} ?
linux-C直接調用SO動態庫和生成SO動態庫的函數
C代碼 ?
#include <stdio.h> ?
#include <dlfcn.h> ?
??
int main(void){ ?
? ?int (*myadd)(int a,int b);//fuction pointer ?
? ?void *handle; ?
? ? ?
? ?handle=dlopen("./libmyadd.so",RTLD_LAZY);//open lib file ?
? ?myadd=dlsym(handle,"output");//call dlsym function ?
? ? ?
??
? ?int result=myadd(1,2); ?
? ?dlclose(handle); ?
? ?printf("%d\n",result); ? ?
} ?
?以上為調用程序test8.c,以下為庫程序test7.c
C代碼 ?
int output(int a,int b){ ?
? ?int x=a+b; ?
? ?return x; ?
} ?
?knoppix@Microknoppix:/mnt-system/deepfuture$ gcc -shared -o libmyadd.so test7.c
knoppix@Microknoppix:/mnt-system/deepfuture$ gcc -ldl -o test8 test8.c
knoppix@Microknoppix:/mnt-system/deepfuture$ ./test8
3
C指針原理(47)-C應用技巧(2)