我正在编写并发(多线程)服务器应用程序 - 使用cource的pthread! - 当我遇到pthread_join的问题时,我的应用程序很糟糕(伪代码):
/* Sheduler thread */
while (1) {
c = get_client();
r = get_resource();
communication.c = c;
communication.r = r;
pthread_create( clnt_tid, null, clnt_fn, communication);
resource_alloc_list_add(clnt_tid, r);
}
/* resources Collector thread */
while(!rs_alloc_list_is_empty()) {
e = get_elt(rs_alloc);
pthread_join(e.clnt_tid, retour);
free_rs(e.r);
}
.........
问题是没有非暴力的pthread_join调用 - 有一个但它不可移植 - 并且pthread_join无法在进程编程中加入任何线程,如wait()。因此,如果rsc_collector线程正在等待一个客户端线程退出以获取已分配的资源,并且在此之前所有其他线程都已退出,则其资源将被阻止 - 并且调度程序线程无法为其他客户端提供服务 - 直到第一个线程终止了他的工作。 你能告诉我这个问题的可能解决方案吗?
编辑:
我将更具体,我正在编写本地资源管理系统(lrms)或远程程序执行系统,有三个不同的程序:客户端pg,服务器pg和调度程序pg,客户端联系调度程序和等待调度程序pg为他分配一个空闲服务器,这样他就可以在提交后,在远程服务器上执行他的工作.sched pg将在客户端队列中对客户端地址进行排队。在另一方面,服务器pg向调度程序发送注册消息并等待作业,调度程序将资源队列中的服务器地址排入队列(因此我的意思是资源是远程服务器而不是系统分配给该线程的资源)。 调度程序pg由三个主线程组成:
注意:
答案 0 :(得分:0)
我建议在退出线程时进行必要的清理,而不是在特殊的收集器线程中。具体来说,使用pthread_key_create()
创建的线程局部数据可能会在线程退出时调用相关的析构函数调用。这个析构函数可以释放与线程相关的应用程序资源;最简单的方法是在特定于线程的槽中存储指向资源的指针(参见pthread_set_specific()
),在这种情况下,指针将自动发送到析构函数。如果线程一直被创建和销毁,收集器线程仍然可以调用pthread_join()
;不过,您也可以创建处于分离状态的线程,或者在创建后调用pthread_detach()
。
另请参阅前面提到的a similar question。
答案 1 :(得分:0)
正如alexey先前所说,线程函数可以分配和释放其资源。如果你想要一个可以处理取消的方法,你也可以使用pthread_cleanup_push和pop。
您可以使用全局标志来告诉您线程是否仍处于活动状态。在创建线程之前将其设置为1,并在线程函数退出时将其设置为0。如果你有很多线程,请使用数组。只需测试变量以查看线程是否完成。
希望你的收集器线程不会持续旋转,这会消耗资源。
创建线程很慢。您可能希望永久保留少量线程,让他们从队列中选择要做的工作。当没有工作时,他们应该等待信号。当工作被添加到队列中时,您可以发出想要唤醒的线程信号并再次开始工作。这比为每个工作创建一个线程快1000倍,并在工作完成时销毁线程。