2-ndk学习之c++基础篇(05)

2020-03-09  本文已影响0人  ftd黑马

文件操作

首先是c语言读取文件:
需要先添加头文件,

#include <ostream> // 输出
#include <istream> // 输入

    // 1,路径
    // 2,模式 r:可以读   w:可以写
    // 写操作
    FILE* file1 = fopen("E:\\NDK\\file.txt", "w");
    fprintf(file1, "今天是多少%d号", 9);
    fclose(file1); // 必须关闭资源

    // 读操作
    FILE* file2 = fopen("E:\\NDK\\file.txt", "r");
    // 定义接受的缓冲
    char buffer[1024]; // 1023 + \0
    fscanf(file2, "%s", buffer);
    cout << "文件里面的内容是:" << buffer << endl;
    fclose(file2);

    // 使用循环读取,内容较多的
    // 缺点:一旦遇到空格,就直接返回
    FILE * file3 = fopen("E:\\NDK\\file.txt", "r");
    char buffer2[1024];
    while (!feof(file3)) {
        fscanf(file3, "%s", buffer2);
        cout << "循环 文件里面的内容是:" << buffer2 << endl;
    }
    fclose(file3);

    // 最常用的,相当于读取一行 一行
    // 遇到换行 或者 遇到 \0 也直接返回了
    // 我们要去解决 上面循环读取的缺点  fgets
    FILE *file4 = fopen("E:\\NDK\\file.txt", "r");
    char buffer3[1025]; // 只能装1024 + \0
    while (!feof(file4)) {
        fgets(buffer3, 1024, file4);
        cout << "循环2 文件里面的内容是:" << buffer3 << endl;
    }
    fclose(file4);

然后是c++读取文件:
先添加头文件:

    #include <ostream>
    #include <istream>
    #include <fstream>

    char * fileVar = "E:\\NDK\\file3.txt";
    // 写入操作
    char data[200];
    ofstream outFile; // 代表以写的模式去打开文件(输出对象)
    outFile.open(fileVar);

    // 获取用户在控制台输入的信息
    cout << "请输入您要保存的信息.." << endl;
    cin >> data; // 执行此行代码后,data就已经数据了,类似于java中的键盘录入,把键盘输入的赋值给了data
    outFile << data << endl;//把data的数据赋值给outFile
    outFile.close();

    // 读取操作
    char mydata[200];
    cout << "开始自动的去读取 刚刚保存到文件里面的内容...." << endl;
    ifstream  ifstreamVar; // 代表输入
    ifstreamVar.open(fileVar);
    ifstreamVar >> mydata;
    // 下面是输出
    cout << mydata << endl;
    ifstreamVar.close();

多线程入门

c++的多线程是一个很难的点,也是很重要的一个点。
我这里使用的是标准库中的pthread库,主要api就是ptrhead_create

void * customPThreadMethod01(void *pVoid){
    int result = *static_cast<int *>(pVoid);
    LOGD("我是耗时操作,%d", result);
    return 0;
}

int main() {
    pthread_t pthread;
    int value = 200;

    /**
     * int pthread_create(pthread_t* __pthread_ptr, 1,线程id
     * pthread_attr_t const* __attr,   2,线程属性
     * void* (*__start_routine)(void*),  3,函数指针---java中的run方法
     * void*);  4,函数指针中传递的值
     */
    pthread_create(&pthread,0,customPThreadMethod01,&value);

    //先让耗时任务执行完毕后,在执行下面的代码
    pthread_join(pthread,0);// join是第二个参数是线程执行完后返回的结果

    LOGD("main函数执行完毕");
    return 0;
}
//这里有个概念是分离线程和非分离线程
// 什么是 分离线程  和 非分离线程 ?
    // 答:非分离线程,要等到耗时任务执行全部完成以后,先执行异步任务,才会执行join后面关联的代码逻辑
    //       分离线程,各玩各的,老死不相往来,所以就造成了,不管异步任务是否执行完毕,该结束就结束

这段代码中,如果不加join函数等待,那么在子线程中result的值是不断变化的,我咨询过c++同事,了解到如果不加线程等待,main函数就有可能在子线程执行结束之前就执行完毕并退出,在这个程序中,value变量定义在主线程(main函数)空间,主线程退出,value变量所在的内存被系统回收,子线程再访问value变量时得到的就是随机值。
也就是说,一般,主线程要保证所有子线程退出后再退出。
所以平时c++开发过程中,遇到多线程,主线程最后都是要调用join函数等待其它线程执行完毕。

线程的安全问题,互斥锁

// 定义一个全局的队列,用于存储使用
queue<int> saveAllData;
// 定义一个互斥锁
pthread_mutex_t pLock; // 互斥锁,不能是野指针,否则是坑
void * customThreadMethod(void * pVoid) {
    // 10条线程,同时运行,并且对队列的数据 “进行操作” 还要保证数据的安全 (加锁)
    pthread_mutex_lock(&pLock);
    if (!saveAllData.empty()) {
        LOGD("获取队列的数据:%d\n", saveAllData.front());
        saveAllData.pop(); // 把数据弹出去,删除的意思
    } else {
        printf("队列中没有数据了\n");
        LOGD("队列中没有数据了\n");
    }
    // 解除锁定,是为了让其他多线程,可以进来的操作,这就是解锁的目的
    pthread_mutex_unlock(&pLock);

    return 0;
}
int main() {
    // 初始化互斥锁
    pthread_mutex_init(&pLock, 0);
    // 给队列初始化数据
    for (int j = 1000; j < 1006; j++) {
        saveAllData.push(j);
    }
    pthread_t pthreadIDArray[10]; // 允许有野指针
    for (int i = 0; i < 3; i++) {
        pthread_create(&pthreadIDArray[i], 0, customThreadMethod, &i);
    }

    system("pause"); // 让main函数,不要去结束,为了演示 多线程

    // 回收互斥锁
    pthread_mutex_destroy(&pLock);
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读