没有二进制信号量会发生什么

What happens without a binary semaphore

假设下面的代码演示了一个二进制信号量示例。

在此示例中,我们有一个 pthread 读取 source.txt 并尝试将内容复制到 destination.txt,同时使用二进制信号量锁定它。

如果没有信号量,下面的评论部分会发生什么?

#include <cstdlib>
#include <memory>
#include <filesystem>
#define _TIMESPEC_DEFINED
#include <pthread.h>
#include <semaphore.h>
#include <thread>
#include <valarray>

pthread_t StartFileAccessThread();
void *CopyFile(void *parameters);

int main(int argc, char* argv[])
{
    pthread_t thread = StartFileAccessThread();

    void *returnValue;
    pthread_join(thread, &returnValue);

    getchar();
    return EXIT_SUCCESS;
}


pthread_t StartFileAccessThread()
{
    std::string sourcePath("source.txt");
    std::string destinationPath("dest.txt");
    sem_t semaphore;
    sem_init(&semaphore, 0, 0);
    pthread_t thread;

    void *parameters[3];
    parameters[0] = &semaphore;
    parameters[1] = &sourcePath;
    parameters[2] = &destinationPath;

    pthread_create(&thread, nullptr, &CopyFile, parameters);

    // What happens without the binary semaphore?
    sem_wait(&semaphore);
    sem_destroy(&semaphore);

    printf("Freeing ressources.\n");

    return thread;
}


void *CopyFile(void *rawParameter)
{
    void **parameters = static_cast<void **>(rawParameter);

    sem_t *semaphore = static_cast<sem_t *>(parameters[0]);
    std::string sourcePath(*static_cast<std::string *>(parameters[1]));
    std::string destinationPath(*static_cast<std::string *>(parameters[2]));

    sem_post(semaphore);

    std::this_thread::sleep_for(std::chrono::seconds(2));

    copy_file(sourcePath, destinationPath, std::experimental::filesystem::copy_options::overwrite_existing);

    printf("File copied \n");

    return nullptr;
}

What happens in the comment section below without the semaphore?

如果没有信号量,函数 startFileAccessThread() 可能会 return 在新线程完成(或开始)从参数对象复制其参数之前。该对象是 startFileAccessThread() 的本地对象,因此它的生命周期在该函数 return 时结束。如果在此之前没有发生复制线程对它的访问,则会导致未定义的行为。