使用Thread和Semaphore的代码

时间:2014-04-27 00:12:39

标签: c multithreading pthreads semaphore

这段代码我做错了什么? 它就像一个票务系统,你有不同的卖家,卖34张票。

#include <stdio.h>
#include <stdbool.h>
#define NUM_TICKETS 35
#define NUM_SELLERS 4
/**
 * The ticket counter and its associated lock will be accessed
 * all threads, so made global for easy access.
 */

static int numTickets = NUM_TICKETS;
static ticketsLock;


/**
 * Our main is creates the initial semaphore lock in an unlocked state
 * (one thread can immediately acquire it) and sets up all of
 * the ticket seller threads, and lets them run to completion. They
 * should all finish when all tickets have been sold. 
 */
void main(int argc, char **argv)
{
    int i;
    char name[32];
    bool verbose = (argc == 2 && (strcmp(argv[1], "-v") == 0));
    InitThreadPackage(verbose);
    ticketsLock = SemaphoreNew("Tickets Lock", 1);
    for (i = 0; i < NUM_SELLERS; i++) {
        sprintf(name, "Seller #%d", i); // give each thread a distinct name
        ThreadNew(name, SellTickets, 0);
    }
    RunAllThreads(); // Let all threads loose
    SemaphoreFree(ticketsLock); // to be tidy, clean up
    printf("All done!\n");
}

static void SellTickets(void)
{
    bool done = false;
    int numSoldByThisThread = 0; // local vars are unique to each thread
    while (!done) {
        /**
         * imagine some code here which does something independent of
         * the other threads such as working with a customer to determine
         * which tickets they want. Simulate with a small random delay
         * to get random variations in output patterns.
         */
        RandomDelay(500000, 2000000);
        SemaphoreWait(ticketsLock); // ENTER CRITICAL SECTION
        if (numTickets == 0) { // here is safe to access numTickets
            done = true; // a "break" here instead of done variable
                         // would be an error- why?
        } else {
            numTickets--;
            numSoldByThisThread++;
            printf("%s sold one (%d left)\n", ThreadName(), numTickets);
        }
        SemaphoreSignal(ticketsLock); // LEAVE CRITICAL SECTION
    }
    printf("%s noticed all tickets sold! (I sold %d myself) \n",
    ThreadName(), numSoldByThisThread);
}

输出应如下所示:

Seller #1 sold one (34 left)
Seller #0 sold one (33 left)
Seller #1 sold one (32 left)
Seller #1 sold one (31 left)
Seller #1 sold one (30 left)
Seller #1 sold one (29 left)
Seller #1 sold one (28 left)
Seller #2 sold one (27 left)
Seller #3 sold one (26 left)
Seller #2 sold one (25 left)
Seller #3 sold one (24 left)
Seller #2 sold one (23 left)
Seller #0 sold one (22 left)
Seller #1 sold one (21 left)
Seller #2 sold one (20 left)
Seller #0 sold one (19 left)
Seller #1 sold one (18 left)
Seller #1 sold one (17 left)
Seller #3 sold one (16 left)
Seller #2 sold one (15 left)
Seller #0 sold one (14 left)
Seller #0 sold one (13 left)
Seller #1 sold one (12 left)
Seller #3 sold one (11 left)
Seller #2 sold one (10 left)
Seller #0 sold one (9 left)
Seller #0 sold one (8 left)
Seller #1 sold one (7 left)
Seller #3 sold one (6 left)
Seller #2 sold one (5 left)
Seller #0 sold one (4 left)
Seller #1 sold one (3 left)
Seller #1 sold one (2 left)
Seller #1 sold one (1 left)
Seller #1 sold one (0 left)
Seller #3 noticed all tickets sold! (I sold 5 myself)
Seller #2 noticed all tickets sold! (I sold 7 myself)
Seller #1 noticed all tickets sold! (I sold 15 myself)
Seller #0 noticed all tickets sold! (I sold 8 myself)
All done!

但编译器告诉我以下内容:  SellTickets()未声明(首次使用此功能)

有人可以帮我解决吗?

谢谢

这是我在切换命令或在main之前声明函数时得到的错误:

/tmp/ccXC17qT.o: In function `main':
new.c:(.text+0x6b): undefined reference to `InitThreadPackage'
new.c:(.text+0x7f): undefined reference to `SemaphoreNew'
new.c:(.text+0xc7): undefined reference to `ThreadNew'
new.c:(.text+0xd8): undefined reference to `RunAllThreads'
new.c:(.text+0xe5): undefined reference to `SemaphoreFree'
/tmp/ccXC17qT.o: In function `SellTickets':
new.c:(.text+0x132): undefined reference to `RandomDelay'
new.c:(.text+0x13f): undefined reference to `SemaphoreWait'
new.c:(.text+0x16a): undefined reference to `ThreadName'
new.c:(.text+0x18c): undefined reference to `SemaphoreSignal'
new.c:(.text+0x19c): undefined reference to `ThreadName'
collect2: ld returned 1 exit status

1 个答案:

答案 0 :(得分:1)

您缺少SellTickets()的函数原型。

将函数原型static void SellTickets(void);置于函数main()之上。

static void SellTickets(void);

void main(int argc, char **argv)
{
   ...
}

static void SellTickets(void)
{
   ...
}

或者您可以更改main()SellTickets()的位置。

static void SellTickets(void)
{
   ...
}

void main(int argc, char **argv)
{
   ...
}

对于与线程相关的其他功能,您必须为#include正确的头文件。之后,它可能会通过编译器,但您还必须链接到正确的库,或者编译和链接这些与线程相关的函数的源代码。你能识别出你正在使用的线程库吗?

谷歌搜索显示这些与线程相关的功能来自此处:http://see.stanford.edu/materials/icsppcs107/22-Thread-Package-Docs.pdf

假设它是您正在使用的线程库, 并且假设头文件和库文件都在编译器和链接器可以找到的正确路径中, 您的程序中#include "thread_107.h,并与libthread_107.a链接。