我试图用一个线程池来编程一个web服务器,在这个线程池中,主线程接受一个连接,将它传递给一个线程,然后线程处理它。
每个线程都有一个结构,并有一个工作队列来保存它们

struct worker {
    pthread_t* thread;
    struct queue* workerQueue;
    char* busy;
    int connfd;
    int id;
};

struct queue {
    int start;
    int end;
    int size;
    struct worker* workers;
};

主线程设置队列和线程,并在连接上循环
  struct queue* workerQueue;
            workerQueue = (struct queue*) constructQueue(10);
            int j;
            int* testParam;
            //create workers and put in queue
            for(j=0;j<5;j++)
            {
                struct worker* w = &(workerQueue->workers[j]);
                w = (struct worker*)constructWorker(processConnection,testParam, workerQueue,j);
                queueAdd(workerQueue,w);
            }
connection = accept(fd, (struct sockaddr *) &cliaddr, &cliaddrlen);
        puts("got connection\n");


         w =(struct worker*) queueRemove(workerQueue);
        //w->connfd = connection;
        w->busy = "BUSY";
        printf("Worker %d has accepted a connection and is %s\n",w->id,w->busy);

使用这两个函数。。
   struct queue* constructQueue(int numThreads)
    {
        struct queue* q = (struct queue *)malloc(sizeof(struct queue));
        q->start = 0;
        q->end = 0;
        q->workers = (struct worker* )malloc(sizeof(struct worker)*numThreads);
        q->size = numThreads;
        return q;
    }

struct worker* constructWorker(void* (*function)(void*),void* param, struct queue* wq, int i)
{
    struct worker* w = (struct worker*)malloc(sizeof(struct worker));
    w->workerQueue = wq;
    char * busy = (char*)malloc(10);
    w->busy= "IDLE";
    w->connfd = 0;
    w->id = i;
    pthread_t t;
    w->thread = &t;
    pthread_create(w->thread,NULL,function,w);
    return w;
}

…线程使用的函数是
void* processConnection(void* serverThread)
{
        //cast serverthread
        struct worker* w;
        char* b;
        int threadID;
        w = (struct worker*)serverThread;
        b = w->busy;
        threadID = w->id;


        while (1)
        {
            char c[10];
            printf("\nbusy: %s, thread: %d\n",b,threadID);
            gets(c)

;
我想发生的是:工人们被创造出来,忙碌被设置为空闲,开始忙碌的等待。然后在主循环中,接受一个连接并将其分配给一个worker,并且将workers busy值设置为busy。然后在processConnections中,如果一个线程很忙,它应该实际处理它。问题是,虽然我的队列包含指针而不是值,但是当我更新主线程中的工作线程时,它似乎不会影响processConnection中的工作线程的值。我可以将busy设置为busy并让它在主循环中打印出来,但是busy的值在processConnection中总是空闲的。有什么想法吗?

最佳答案

可能在另一个线程中看不到更新的值,因为线程之间没有同步点。编译器优化和缓存(in)一致性是发生这种情况的两个原因。为了保持同样的策略,你需要一个记忆障碍。如果使用gcc,最简单的方法是在读取共享数据之前和写入共享数据之后放置__sync_synchronize()
另一件事你需要解决的是当你

pthread_t t;
w->thread = &t;

t的内存在该函数返回后容易被重用。不能获取局部变量的地址,并以比函数生存期更长的方式存储它。正确的做法是在pthread_t中有一个struct worker字段,并将该字段的地址传递给pthread_create
pthread_create(&w->thread, ...);

10-04 12:42