gpt4 book ai didi

c++ - 分离线程的参数问题

转载 作者:行者123 更新时间:2023-11-28 06:54:29 24 4
gpt4 key购买 nike

我正在做一个学校项目(模拟虚拟内存),我们应该在其中使用分离线程。我们可以使用的内容也有其他限制,但我稍后会提到。问题是当我给 pthread_create 函数最后一个参数作为 (void*)something 并且创建的线程被分离时,pthread_create 调用的函数将接收参数,但是由于线程被分离,原始参数被尽快删除因为我调用 pthread_create 的函数完成了——这意味着被调用函数中的参数不再有效,因此我得到了段错误等。这是代码的一部分(无法完整发布,它非常大):

bool CProcManager::NewProcess(void* processArg, void(*entryPoint)(CCPU*, void*), bool copyMem) {
uint32_t free_page;
pthread_attr_t attr;
pthread_t thread;

if (proc_cnt >= 63)
return 0;

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

if (!FindFreePage(free_page)) return 0;

free_page = (free_page << 12) | 7;
CProcManager ccpu(m_MemStart, free_page);
ThrArgs args(entryPoint, (void *) processArg, ccpu);

proc_cnt++;
if (pthread_create(&thread, NULL, StartWork, (void *) &args))
return 0;

//pthread_mutex_lock(&start_mtx);
//pthread_cond_wait(&start_cond, &start_mtx);
//pthread_mutex_unlock(&start_mtx);

return 1;
}

在这里你可以看到这个函数得到了一个指向void的指针和一个指向函数的指针作为参数。 pthread_creates 告诉线程使用参数“args”调用“StartWork”函数,参数“args”是一个包含函数指针、void 指针和 CProcManager 类型对象的结构。

void* CProcManager::StartWork(void* arguments) {
//pthread_mutex_lock(&start_mtx);
ThrArgs *args = (ThrArgs*) arguments;
CProcManager ccpu = args->ccpu;

//pthread_cond_signal(&start_cond);
//pthread_mutex_unlock(&start_mtx);

args->entryPoint(&ccpu, args->processArg);

ccpu.RemovePage((ccpu.m_PageTableRoot >> 12) * PAGE_SIZE, false);

pthread_mutex_lock(&end_mtx);
proc_cnt--;
pthread_cond_signal(&end_cond);
pthread_mutex_unlock(&end_mtx);
return (NULL);
}

在这个函数中,我最终调用了我有指针指向的函数。你可以猜到,当“NewProcess”函数结束时参数变得无效,所以我试图通过添加一个条件变量来克服这个问题,并以某种方式复制我的参数(还没有找到解决方案)然后让“NewProcess”函数结束。但是这个项目有一定的局限性。函数“NewProcess”被多次调用并且线程应该同时运行(我尝试在调用 entryPoint 后向条件变量发送信号并且有效),所以我无法完成一个线程然后执行下一个线程。第一个函数的参数“void* processArg”本来就是某个对象类型,上面两个函数都访问不到这个类型。

那么谁能给我一个如何复制参数的建议,这样我就不会出现段错误?

最佳答案

问题非常简单,是对象生命周期和所有权的问题之一。

您正在将“args”的地址传递给线程,但是“args”是在堆栈上创建的,并且在线程启动后很快就超出了范围。

像这样做:

// note: The ThrArgs constructor should take ownership of processArg
std::unique_ptr<ThrArgs> args (new ThrArgs(entryPoint, (void *) processArg, ccpu));
if (pthread_create(&thread, NULL, StartWork, (void *) args.get())) {
args.release();
// ownership of the pointer now belongs to the thread
return 0;
}

然后在线程函数中:

void* CProcManager::StartWork(void* arguments) {
std::unique_ptr<ThrArgs> args (reinterpret_cast<ThrArgs*>(arguments));

// now use args as a pointer

....


// the arguments will be deleted here
return 0;
}

关于c++ - 分离线程的参数问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23345644/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com