C指针原理(47)-C应用技巧
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C指针原理(47)-C应用技巧相关的知识,希望对你有一定的参考价值。
委托模型,即有一个BOSS线程,就是主线程,产生woker线程,boss线程和worker线程并发执行。
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 newthread,
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
exit status of the thread is stored in THREAD_RETURN, if THREAD_RETURN
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
",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
",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);
}
执行效果:
[email protected]:~/mytest$ gcc -lpthread -std=c99 -o main main.c
[email protected]:~/mytest$ ./main
add3
chen6
[email protected]:~/mytest$?
C-多线程-取消及取消点
?
线程取消
编译:
gcc -std=c99 -lpthread -o main main.c
?
deep[email protected]:~/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 不能被取消!br/>[email protected]:~/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
",*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
",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
",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 已经取消!
",i); ?
? ? ? ?} ?
? ? ? ?else{ ?
? ? ? ? printf("thread%d 不能被取消!
",i); ?
? ? ? ?} ? ? ?
? ? ? ? ?
? } ??
? return(0); ?
} ?
?
c-多线程-中止前清理
gcc -lpthread -std=c99 -o main main.c
[email protected]:~/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
",*((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
",*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
",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
",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 已经取消!
",i); ?
? ? ? ?} ?
? ? ? ?else{ ?
? ? ? ? printf("thread%d 不能被取消!
",i); ?
? ? ? ?} ? ? ?
? ? ? ? ?
? } ??
? return(0); ?
} ?
?linux-线程优先级
C代码 ?
#include <pthread.h> ?
#include <stdio.h> ?
??
#define MAXTHREADS 3 ??
void *myclear(void *x){ ?
? ?printf("clear:%d
",*((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
",*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
",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
",size); //输出线程堆栈大小 ? ??
??
??
? int sum=1; ??
? int *x=(int *)(xx); ?
? for (int i=1;i<=*x;i++){ ?
? ? sum*=i; ? ? ?
? ? printf("%dchen%d
",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 已经取消!
",i); ?
? ? ? ?} ?
? ? ? ?else{ ?
? ? ? ? printf("thread%d 不能被取消!
",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
",result); ? ?
} ?
?以上为调用程序test8.c,以下为库程序test7.c
C代码 ?
int output(int a,int b){ ?
? ?int x=a+b; ?
? ?return x; ?
} ?
[email protected]:/mnt-system/deepfuture$ gcc -shared -o libmyadd.so test7.c
[email protected]:/mnt-system/deepfuture$ gcc -ldl -o test8 test8.c
[email protected]:/mnt-system/deepfuture$ ./test8
3
以上是关于C指针原理(47)-C应用技巧的主要内容,如果未能解决你的问题,请参考以下文章