星期一, 十月 02, 2006

OS说:要更多并发,于是有了多线程

这里我将说明一下自己在使用pthread遇到的一些问题,顺便作为这里长期空白的补丁。

先做一个广告好了。我的系统是ubuntu6.06 Dapper Drake,相信现在使用这个发行版本的用户数量是最为庞大的。而且由于Debian的强大支持,这个系统在安装和使用中都是非常适合入门,以及拥有相当Linux知识的人士使用。不过默认情况下是没有gcc和make这些东西的,只有一个链接器ld被安装。所以,之前请安装它们两个软件。(用sudo执行apt-get install gcc make 即可。)不过如果你需要边听着mp3边工作的话,请自己搜索一下让rhythmbox支持它的方法吧。

网络知识资源:pthread入门 这是我强力推荐的站点。
IBM的developerWorks的thread专栏 下面也有很多关于Linux的线程问题的讨论,用心挖掘会了解很多有益的东西的。
当然,如果手边有一本像样的pthread书籍的话那就更加完美了。

现在可以创建你的C文件,并include像是unistd.h, stdio.h, 当然还有pthread.h这些文件。

如何创建线程?
只用这一句即可:
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
不过里面的参数却要说明一下。
首先是thread1这个参数,它是pthread_t类型的,作为返回值告诉我们创建的这个线程编号。而print_message_function和message1则是线程函数和它的入参了。返回值表示成功与否。

然后呢?
当然是线程开始工作。但是主线程,也就是创建它的那个线程该怎么办呢?它的使命结束了吗?
我们可以在创建一个线程后结束自己,然后看看会怎么样。
int main()
{
pthread_t threadid;
int ret;

ret = pthread_create( &threadid, NULL,
print_message_function, (void*)msgarg);
//pthread_join(threadid, NULL);
printf("I, the father process(%d) is exitting..\n", getpid());
exit(0);
}

void *print_message_function( void *ptr )
{
sleep(5);
puts((const char*) ptr);
return NULL;
}
结果就是完全看不到线程输出的信息,查看进程表的结果也同样说明了这个问题。主线程的结束将终结所有子线程。
这和在网络上看到一些言论不太一样,据报道有人在主线程先于子线程结束的情况下发现整个进程变成了“僵尸”
不过这里没有发现这种情况。

但是一般意义上,子线程的退出应该是可以预料的,比如使用一个全局的符号或者消息来通知它们。而不是如此粗暴的关闭程序,这样我们无法全面释放任务线程所占用的资源,这时候就需要在上面一段中被注释的那一行代码了--使用pthread_join来等待创建的线程结束。
(关于资源的占用和释放的主题请关注pthread_cleanup_push和pthread_cleanup_pop的相关内容。)

(待续……)

没有评论: