子线程操作malloc内存
2016-06-29 09:21
239 查看
这个问题的引出是由于,在实际应用过程中遇到主程序需要调用独立的功能模块(API),并获取其返回结果,
可以通过文件操作,将功能模块生成结果写入日志,主程序读取日志结果,而主程序提取日志信息后,要需要形成新的
日志文件,这个过程就涉及到三次文件打开关闭操作,影响软件性能;
API实际处理运算是在其内部创建的子线程的子线程(该API是在第三方API基础封装)中完成,线程创建过程能够传递
(void *)类型的参数,按照上面文件的操作也是将文件名作为字符串传入线程任务函数,处理结果形成特定的文件名的
日志;既然能够传递字符串,为何不直接传递可操作的地址到线程内部,直接将处理结果写入到地址中,于是就有了另外
的方法,在调用该API的主程序中先malloc申请一段内存(ch)用来存储处理结果,将内存首地址作为API形参传入,
然后将地址的数值转化为字符串(addr_ch),通过创建线程时传入到线程任务函数中,在线程内存先通过atoi库函数转化成
unsigned long存储(addr),接着强制转化成地址指针,最后就可以操作malloc的地址了(因为malloc申请内存在堆区,唯一性)。
测试代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void *task(void *data){
printf("Enter thread.\n");
char *addr_ch = data;
printf("thread:addr_ch:%s\n",addr_ch);
unsigned long addr = atoi(addr_ch); //地址字符串存储成数值
printf("thread:addr:%ld\n",addr);
char *ch = (char *)addr; //强转成地址指针
*ch = 'B'; //操作地址
printf("thread:%c\n",*ch);
sleep(3);
return NULL;
}
int main(int argc,char *argv[]){
char *ch = malloc(sizeof(char)); //malloc一个char
char addr_ch[15] = {0}; //用来存储ch的地址
sprintf(addr_ch,"%d",ch); //ch地址转化为字符串存储到addr_ch
pthread_t td;
if(pthread_create(&td,NULL,task,(void *)addr_ch)) //创建线程,并将地址字符串addr_ch作为参数传入线程task
printf("pthread_create failed.\n");
pthread_join(td,NULL); //等待子线程处理完成
printf("Thread return.\n"); //检测子线程的操作是否生效
printf("main:%c\n",*ch);
free(ch);
ch = NULL;
return 0;
}
通编译:gcc xxx.c -lpthread
可执行程序:a.out
执行a.out就可以看到在子线程内存成功操作主线程的malloc存储区域,线程处理的这部分功能就可以封装成API,然后预留
用来传递malloc地址的接口,这样API处理的结果就直接通过接口参数返回给主程序,当然该API接口可设定返回值用来给主
程序判定是否成功处理,0成功-1失败,根据返回值来判定是否操作之前malloc的内存。
功底有限,还需努力。
可以通过文件操作,将功能模块生成结果写入日志,主程序读取日志结果,而主程序提取日志信息后,要需要形成新的
日志文件,这个过程就涉及到三次文件打开关闭操作,影响软件性能;
API实际处理运算是在其内部创建的子线程的子线程(该API是在第三方API基础封装)中完成,线程创建过程能够传递
(void *)类型的参数,按照上面文件的操作也是将文件名作为字符串传入线程任务函数,处理结果形成特定的文件名的
日志;既然能够传递字符串,为何不直接传递可操作的地址到线程内部,直接将处理结果写入到地址中,于是就有了另外
的方法,在调用该API的主程序中先malloc申请一段内存(ch)用来存储处理结果,将内存首地址作为API形参传入,
然后将地址的数值转化为字符串(addr_ch),通过创建线程时传入到线程任务函数中,在线程内存先通过atoi库函数转化成
unsigned long存储(addr),接着强制转化成地址指针,最后就可以操作malloc的地址了(因为malloc申请内存在堆区,唯一性)。
测试代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void *task(void *data){
printf("Enter thread.\n");
char *addr_ch = data;
printf("thread:addr_ch:%s\n",addr_ch);
unsigned long addr = atoi(addr_ch); //地址字符串存储成数值
printf("thread:addr:%ld\n",addr);
char *ch = (char *)addr; //强转成地址指针
*ch = 'B'; //操作地址
printf("thread:%c\n",*ch);
sleep(3);
return NULL;
}
int main(int argc,char *argv[]){
char *ch = malloc(sizeof(char)); //malloc一个char
char addr_ch[15] = {0}; //用来存储ch的地址
sprintf(addr_ch,"%d",ch); //ch地址转化为字符串存储到addr_ch
pthread_t td;
if(pthread_create(&td,NULL,task,(void *)addr_ch)) //创建线程,并将地址字符串addr_ch作为参数传入线程task
printf("pthread_create failed.\n");
pthread_join(td,NULL); //等待子线程处理完成
printf("Thread return.\n"); //检测子线程的操作是否生效
printf("main:%c\n",*ch);
free(ch);
ch = NULL;
return 0;
}
通编译:gcc xxx.c -lpthread
可执行程序:a.out
执行a.out就可以看到在子线程内存成功操作主线程的malloc存储区域,线程处理的这部分功能就可以封装成API,然后预留
用来传递malloc地址的接口,这样API处理的结果就直接通过接口参数返回给主程序,当然该API接口可设定返回值用来给主
程序判定是否成功处理,0成功-1失败,根据返回值来判定是否操作之前malloc的内存。
功底有限,还需努力。
相关文章推荐
- leetcode@ [316] Remove Duplicate Letters (Stack & Greedy)
- 缓存外部系统接口返回信息的方案
- iOS Provisioning Profile总莫名其妙失效问题
- 大数据的仓库Hive原理(二)
- linux常用命令
- 设计模式---工厂模式
- Arch linux 的安装
- Android教程之开机流程全面解析
- php session 管理
- 标记 Arduino M0 板子如何更改PWM输出频率
- 使用java MapReduce job 批量导入大额数据到Hbase
- 浅谈Angular的 $q, defer, promise
- .lib和.dll的区别和使用
- MySQL单表百万数据记录分页性能优化
- 我的shiro之旅-注解方式授权
- php session 管理
- php session 管理
- java 中final关键字(转)
- 编写业务逻辑代码-清晰可维护才是最重要的
- 软件工程师关注的播客