C指针原理(47)-C应用技巧(2)

委托模型,即有一个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\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 不能被取消!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,&param);//动态设置调度策略  
//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,&param);//通过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

猜你喜欢

转载自blog.51cto.com/13959448/2342823