【问题标题】:C linux pthread needs sleep to workC linux pthread需要睡眠才能工作
【发布时间】:2012-12-28 13:37:16
【问题描述】:

我正在使用 gcc 在 linux 上用 c 编写程序。 如果我不使用那个睡眠语句 它将随机打印 2,3 或 4 次“线程创建”。谁能解释我这种行为? //下面的代码只是一个示例,我知道创建一个线程只是为了打印一个字符串并不是很有用:)

void* makeRequest(void* arg) {
    printf("Thread created\n");
}

int main(){
   pthread_t thr[10];
   for(i=0; i<3; i++){  
       pthread_create(&thr[i], 0, makeRequest, &i);
       sleep(1);
    }
 }

附言我包括了 pthread.h 和编译选项 -pthread

【问题讨论】:

    标签: c linux gcc pthreads


    【解决方案1】:

    你应该加入你创建的所有线程,结束main,因为你退出整个过程。

    或者,您可以使用 pthread_exit 结束您的 main

    【讨论】:

    • 所以 pthread 连接必须在 for 语句之后完成? (我的程序相当复杂,“for”语句必须无限次执行,因为它等待客户端请求;当客户端请求存在时,它将创建3个线程)while(1){for(i=0; i&lt;3; i++){ pthread_create(&amp;thr[i], 0, makeRequest, &amp;i); sleep(1); }}
    • 您只需要确保您的main 不会在您的任何其他线程之前结束。所以,是的,连接必须位于for 循环中线程的创建和main 的终止之间。
    【解决方案2】:

    除此之外,

     pthread_create(&thr[i], 0, makeRequest, &i);
    

    不正确,因为i 是一个局部变量,所以&amp;i 是您对pthread_create 的所有调用的同一个指针

    您通常应该将数据指针指向您的线程例程 - 这里的线程例程是makeRequest 静态指针或唯一指针(每个线程唯一);在实践中,让它成为一些malloc-ed 内存的指针。

    更好的做法是声明一些struct my_thread_data_st,用

    在堆中唯一地分配它
    struct my_thread_data_st* td = malloc(sizeof(struct my_thread_data_st));
    if (!td) perror("malloc td"), exit(EXIT_FAILURE);
    memset (td, 0, sizeof(struct my_thread_data_st));
    // fill td appropriately, then
    pthread_create(&thr[i], 0, makeRequest, td);
    

    或者你可以有一个数组,例如int-s,例如int num[4];,适当初始化,然后pthread_create(&amp;thr[i], 0, makeRequest, &amp;num[i]);

    当然,如果td 是通过malloc 进行堆分配的,请不要忘记在适当的时间使用free,例如线程结束后(例如,在 pthread_join-ed 之后)。您可能还对Boehm's GC 感兴趣,并使用GC_malloc 而不是malloc(那么,不用担心释放内存,GC 会这样做)。

    如果线程正在访问共享数据,您应该使用一些 [全局或静态] 互斥锁(使用 pthread_mutex_lockpthread_mutex_unlock)序列化对它的访问

    在退出之前不要忘记在所有线程上调用pthread_join -e.g.从main返回。

    我建议阅读一些pthreads tutorial 和一些关于advanced linux programming 的书。

    【讨论】:

    • 非常感谢您非常详细的回答。它对我的堆内存分配帮助很大。建议。再次非常感谢:)
    【解决方案3】:

    你需要:

    for(i = 0; i < 3; i++)
    {
       pthread_join(thr[i], NULL);
    }
    

    正如你所写的,在 main 返回并退出整个进程之前,没有任何东西等待你的线程完成,从而杀死线程。

    【讨论】:

      【解决方案4】:

      先用join:,不用的话不用发&amp;i

      随机打印“线程创建”2,3 或 4 次。

      当主线程死亡时,所有子线程也会死亡。所以你需要等待加入。

      随机。:因为我们不知道在线程上下文切换中哪个会获得机会。它可能是主线程或子线程。

      for(i=0; i<3; i++){  
             pthread_create(&thr[i], 0, makeRequest, &i);   
      }
      
      for(i=0; i<3; i++){  
             pthread_join(thr[i], NULL);
      }
      

      第二使用-lpthread -pthread

      $ gcc file.c -lpthread -o output      
      

      已编辑

      -pthread 通过“pthreads”库添加对多线程的支持。此选项为预处理器和链接器设置标志:Jens Gustedt comment

      Difference between -pthread and -lpthread

      【讨论】:

      • 感谢 -lpthread 的建议,我会阅读更多关于此的内容 //我知道我不需要发送那个 "i" ,但正如我之前所说的,这只是一个示例,(整个代码大约有 500 行)
      • @nickNatra 但我不认为"thread created" 打印了 4 次,它可能最多打印 3 次。
      • @GrijeshChauhan, -pthread 是 gcc 的正确选项。它比-lpthread 做的更多:“-pthread 通过“pthreads”库添加对多线程的支持。此选项为预处理器和链接器设置标志。”
      • @JensGustedt : 哦..我不知道 -pthread :(。我当时弄错了...但是我在 google-search 中没有找到这个选项。
      猜你喜欢
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 2012-04-17
      • 2015-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多