C++ 多线程和互斥锁

c++ multithreading and mutex

本文关键字:多线程 C++      更新时间:2023-10-16

我对C/Linux多线程有点熟悉,但这次我必须在Windows上使用C++做一些工作,但我无法掌握它。在我的程序中,我有 2 个函数不断尝试访问同一个文件以执行一些打印操作,发生的事情是其中一个永远不会工作,这让我认为一个函数永远无法打开文件,因为另一个函数总是可以在上面书写。如何实现线程来实现此工作?代码大致如下:

std:mutex mut;
    main(){
        while(1){
            //get mychar from user
            print1(mychar, "my.txt");
            print2();
        }
    }
print1(int i, char* file){
    FILE *f = fopen(file, "a");
    /*print operations
    ..
    .*/
    fclose(f);
    return 0;
}
void print2(){
    /*getting a string
    ...
    Sleep(200);
    getting another string
    ...*/
    char getX[];  //fill buffers with the strings accordingly
    char getY[]; //basically i want to know if the initial string has changed
    if(*getX != *getY){
        std::Lock_guard<std::mutex> guard(mut);
        FILE *f = fopen("my.txt", "a");
        fprintf(f, "%s ", getY);
        fclose(f);
    }
    getX = NULL;
    getY = NULL;
}

第一个问题是你的互斥锁是在main中本地声明的。它们需要可供您的函数访问。如果程序中所有相关的事情都发生在这个文件中,那么使用全局声明的互斥锁是完全可以的。

第二个问题是您没有正确锁定任一线程。如果您要打开两个文件进行追加,那么最安全的做法是在打开时锁定并在关闭时解锁。您可以通过在函数条目上使用全局互斥锁初始化锁保护来实现此目的:

std::mutex mut;
main(){
    while(1){
        //get mychar from user
        print1(mychar, "my.txt");
        print2();
    }
}
print1(int i, char* file){
    std::lock_guard<std::mutex> guard(mut);
    FILE *f = fopen(file, "a");
    /*print operations
    ..
    .*/
    fclose(f);
    return 0;
}
void print2(){
    /*getting a string
    ...
    Sleep(200);
    getting another string
    ...*/
    char getX[];  //fill buffers with the strings accordingly
    char getY[]; //basically i want to know if the initial string has changed
    if(*getX != *getY){
        std::lock_guard<std::mutex> guard(mut);
        FILE *f = fopen("my.txt", "a");
        fprintf(f, "%s ", getY);
        fclose(f);
    }
    getX = NULL;
    getY = NULL;
}

正如其他人指出的那样,您甚至在这里都没有使用并发性。这只是一个接一个的函数调用。如果要使用线程,可以在while(1)循环中执行此操作:

while(1){
    std::thread thread1(print1, mychar, "my.text");
    std::thread thread2(print2);
    thread1.join();
    thread2.join();
}
编辑

:我已经编辑了您的print2函数,使其仅在需要写入文件时才打开文件。这使得并发在应用程序结构中更加明智。