0

我正在使用 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);
    }
 }

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

4

4 回答 4

4

您应该加入您创建的所有线程,main并在您退出整个过程时结束。

或者,您可以mainpthread_exit.

于 2012-12-28T13:39:44.133 回答
2

除了其他备注外,

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

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

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

更好的做法是声明 some 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(&thr[i], 0, makeRequest, &num[i]);

当然,如果td是 heap-allocated thru malloc,请不要free在适当的时候忘记它,例如在线程结束之后(例如在pthread_join之后)。您可能还对Boehm 的 GC感兴趣并使用GC_malloc而不是malloc(然后,不要担心释放内存,GC 会这样做)。

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

不要忘记pthread_join在退出之前调用所有线程 - 例如从main.

我建议阅读一些pthreads 教程和一些关于高级 linux 编程的书。

于 2012-12-28T17:00:18.383 回答
1

你需要:

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

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

于 2012-12-28T13:39:58.817 回答
1

先用join:,&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 评论

-pthread 和 -lpthread 之间的区别

于 2012-12-28T13:43:34.747 回答