等待()通过克隆创建的线程?

wait() for thread made via clone?

我打算将其重写为程序集,这样我就不能使用 c 或 c++ 标准库了。下面的代码运行完美。但是我想要一个线程而不是第二个进程。如果您在第 25 行取消注释 /*CLONE_THREAD|*/waitpid 将 return -1。我想要一个阻塞函数,当我的线程完成时它会恢复。我无法通过查看手册页弄清楚它希望我做什么

#include <sys/wait.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>

int globalValue=0;

static int childFunc(void*arg)
{
    printf("Global value is %d\n", globalValue);
    globalValue += *(int*)&arg;
    return 31;
}

int main(int argc, char *argv[])
{
    auto stack_size = 1024 * 1024;
    auto stack = (char*)mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
    if (stack == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); }

    globalValue = 5;

    auto pid = clone(childFunc, stack + stack_size, /*CLONE_THREAD|*/CLONE_VM|CLONE_SIGHAND|SIGCHLD, (void*)7);
    sleep(1); //So main and child printf don't collide
    if (pid == -1) { perror("clone"); exit(EXIT_FAILURE); }
    printf("clone() returned %d\n", pid);

    int status;
    int waitVal = waitpid(-1, &status, __WALL);

    printf("Expecting 12 got %d. Expecting 31 got %d. ID=%d\n", globalValue, WEXITSTATUS(status), waitVal);
    return 0;
}

如果你想用线程异步调用函数,我建议使用 std::async。这里的例子:

#include <iostream>
#include <future>
#include <mutex>
#include <condition_variable>

int globalValue = 0;    // could also have been std::atomic<int> but I choose a mutex (to also serialize output to std::cout)
std::mutex mtx;         // to protect access to data in multithreaded applications you can use mutexes 

int childFunc(const int value)
{
    std::unique_lock<std::mutex> lock(mtx);
    globalValue = value;
    std::cout << "Global value set to " << globalValue << "\n";
    return 31;
}

int getValue()
{
    std::unique_lock<std::mutex> lock(mtx);
    return globalValue;
}

int main(int argc, char* argv[])
{
    // shared memory stuff is not needed for threads

    // launch childFunc asynchronously
    // using a lambda function : https://en.cppreference.com/w/cpp/language/lambda
    // to call a function asynchronously : https://en.cppreference.com/w/cpp/thread/async
    // note I didn't ues the C++ thread class, it can launch things asynchronously
    // however async is both a better abstraction and you can return values (and exceptions)
    // to the calling thread if you need to (which you do in this case)
    std::future<int> future = std::async(std::launch::async, [] 
    {
        return childFunc(12); 
    });

    // wait until asynchronous function call is complete
    // and get its return value;
    int value_from_async = future.get();

    std::cout << "Expected global value 12, value = " << getValue() << "\n";
    std::cout << "Expected return value from asynchronous process is 31, value = " << value_from_async << "\n";
    return 0;
}