C++ 在线程退出时重新启动线程

C++ 在线程退出时重新启动线程,c++,multithreading,pthreads,C++,Multithreading,Pthreads,我有一个线程化的fcgi应用程序,它生成N个线程,并在退出之前等待它们完成 #include "vips/vips.h" #include "vips/vips" #include <stdio.h> #include <stdlib.h> #include <iostream> #include "tiff.h" #include "tiffio.h" #include "fastcgi.h" #include "fcgio.h" #include "Tok

我有一个线程化的fcgi应用程序,它生成N个线程,并在退出之前等待它们完成

#include "vips/vips.h"
#include "vips/vips"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "tiff.h"
#include "tiffio.h"
#include "fastcgi.h"
#include "fcgio.h"
#include "Tokenizer.h"
#include "string.h"
#include <sstream>
#include <pthread.h>
#include <sys/types.h>

using namespace std;
using namespace vips;

#define THREAD_COUNT 2
static int counts[THREAD_COUNT];

static void *handleFcgi(void *a)
{
    int rc, i, thread_id = (intptr_t)a;
    pid_t pid = getpid();
    FCGX_Request request;
    char *server_name;

    FCGX_InitRequest(&request, 0, 0);
    for (;;)
    {
        static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER;
        static pthread_mutex_t counts_mutex = PTHREAD_MUTEX_INITIALIZER;

        /* Some platforms require accept() serialization, some don't.. */
        pthread_mutex_lock(&accept_mutex);
        rc = FCGX_Accept_r(&request);
        pthread_mutex_unlock(&accept_mutex);

        if (rc < 0 || counts[thread_id] > 5)
            break;

        server_name = FCGX_GetParam("SERVER_NAME", request.envp);

        FCGX_FPrintF(request.out,
                     "Content-type: text/html\r\n"
                     "\r\n"
                     "<title>FastCGI Hello! (multi-threaded C, fcgiapp library)</title>"
                     "<h1>FastCGI Hello! (multi-threaded C, fcgiapp library)</h1>"
                     "Thread %d, Process %ld<p>"
                     "Request counts for %d threads running on host <i>%s</i><p><code>",
                     thread_id, pid, THREAD_COUNT, server_name ? server_name : "?");

        pthread_mutex_lock(&counts_mutex);
        ++counts[thread_id];
        for (i = 0; i < THREAD_COUNT; i++)
            FCGX_FPrintF(request.out, "%5d " , counts[i]);
        pthread_mutex_unlock(&counts_mutex);

        FCGX_Finish_r(&request);
    }

    return NULL;
}

int main (int argc, char **argv)
{
    int i;
    pthread_t id[THREAD_COUNT];
    FCGX_Init();

    for (i = 0; i < THREAD_COUNT; i++)
        pthread_create(&id[i], NULL, handleFcgi, (void*) i);

    pthread_join(id[0], NULL);
    pthread_join(id[1], NULL);

    return(0);
}
#包括“vips/vips.h”
#包括“贵宾/贵宾”
#包括
#包括
#包括
#包括“tiff.h”
#包括“tiffio.h”
#包括“fastcgi.h”
#包括“fcgio.h”
#包括“Tokenizer.h”
#包括“string.h”
#包括
#包括
#包括
使用名称空间std;
使用名称空间VIP;
#定义线程计数2
静态整数计数[线程计数];
静态void*handleFcgi(void*a)
{
int rc,i,thread_id=(intptr_t)a;
pid_t pid=getpid();
FCGX_请求;
字符*服务器名称;
FCGX_InitRequest(&request,0,0);
对于(;;)
{
静态pthread\u mutex\u t accept\u mutex=pthread\u mutex\u初始值设定项;
静态pthread\u mutex\u t counts\u mutex=pthread\u mutex\u初始值设定项;
/*有些平台需要accept()序列化,有些则不需要*/
pthread_mutex_lock(&accept_mutex);
rc=FCGX\u接受请求(&r);
pthread_mutex_unlock(&accept_mutex);
如果(rc<0 | |计数[线程id]>5)
打破
server_name=FCGX_GetParam(“server_name”,request.envp);
FCGX_FPrintF(request.out,
“内容类型:text/html\r\n”
“\r\n”
FastCGI Hello!(多线程C,fcgiapp库)
FastCGI Hello!(多线程C,fcgiapp库)
线程%d,进程%ld
“主机%s上运行的%d个线程的请求计数”,
线程id、pid、线程计数、服务器名称?服务器名称:“?”;
pthread_mutex_lock(&counts_mutex);
++计数[线程id];
对于(i=0;i
我现在已经将线程设置为在5个请求后完成,因为稍后我将添加一些自定义逻辑,并且我希望在一些请求后完全重新启动线程


我希望每次有一个线程存在时生成一个线程,这可能吗?

简单的回答是,如果让线程退出,则必须生成一个新线程。一旦线程退出,您就无法重新启动它,此时系统已拆除该线程。你只需要创建一个新的线程,或者保持原来的线程处于活动状态,直到你不需要它为止

根据你刚才所说的,为什么不考虑使用一个线程池,比如Booo::线程池。这将为您节省大量生成新线程的开销,因为这是一个相当昂贵的操作


线程池基本上是一个线程池,操作系统可以使用它来分配工作。这样,您就不需要创建新的线程,也不需要为管理线程操心太多,您只需将工作交给它们即可获得结果

简单的回答是,如果让线程退出,那么必须生成一个新线程。一旦线程退出,您就无法重新启动它,此时系统已拆除该线程。你只需要创建一个新的线程,或者保持原来的线程处于活动状态,直到你不需要它为止

根据你刚才所说的,为什么不考虑使用一个线程池,比如Booo::线程池。这将为您节省大量生成新线程的开销,因为这是一个相当昂贵的操作


线程池基本上是一个线程池,操作系统可以使用它来分配工作。这样,您就不需要创建新的线程,也不需要为管理线程操心太多,您只需将工作交给它们即可获得结果

是的,对不起,我是说重生。我将编辑问题+1-使用一个池和一些屏障/集合点来表示任务完成。Create/Start/Join/Terminate是浪费、低效、难以管理的,而且非常糟糕。如果你有一本教科书或页面提到在任何其他线程间通信或同步机制之前加入,烧掉它或删除它的书签。我将编辑问题+1-使用一个池和一些屏障/集合点来表示任务完成。Create/Start/Join/Terminate是浪费、低效、难以管理的,而且非常糟糕。如果您有一本教科书或页面在任何其他线程间通信或同步机制之前提到Join,请烧掉它或删除它的书签。您真的需要所有这些标题吗?和:比起C标题,更喜欢C++标题(例如,而不是代码> STDIO .H./CODE,使用<代码> CSTDIO < /COD>)那些标题是我稍后要做的图像处理,因为我的单线程版本工作得很好,现在我隔离了多线程代码来询问。你真的需要所有的头吗?和:比起C标题,更喜欢C++标题(例如,而不是代码> STDIO .H./Cube >,使用<代码> CSTDIO < /代码>)那些标题是我稍后要做的图像处理,因为我的单线程版本工作得很好,现在我把多线程代码隔离开来,在这里请求。