|
程序只有 2 个线程,通过该示例,了解多线程编程的基本框架与工作原理。
程序代码:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
void *thread_function (void *arg);
char message [] = "Hello World";
int main ()
{
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create (&a_thread, NULL, thread_function, (void *)message);
if (res != 0) {
perror ("Thread creation failed");
exit (EXIT_FAILURE);
}
printf ("Waiting for thread to finish...\n");
res = pthread_join (a_thread, &thread_result);
if (res != 0) {
perror ("Thread join failed");
exit (EXIT_FAILURE);
}
printf ("Thread joined, it returen %s\n", (char *)thread_result);
printf ("Message is now %s\n", message);
exit (EXIT_SUCCESS);
}
void *thread_function (void *arg)
{
printf ("thread_function is running. Argument was %s\n", (char *)arg);
sleep (3);
strcpy (message, "Bye!");
pthread_exit ("Thank you for the CPU time");
}
多线程程序的编译方法:
编译多线程程序,首先需要确保 _REENTRANT 已被定义。在少数系统上,或许还需要定义 _POSIX_C_SOURCE ,但通常情况下这并不必要。
编译多线程程序,还需要链接相关的线程库。一般的,在 /usr/include/ 下应该可以找到 pthread.h 头文件,如果文件的头部所声明的版权日期是 2003 年及以后,那么基本上可以确定是基于 NPTL 实现。
在确定已经安装好所需文件后,可用下面的方法编译与链接:gcc -D_REENTRANT -I/usr/include/nptl thread1.c -o thread1.exe -L/usr/lib/nptl -lpthread
如果,NPTL 已经默认在系统里(现在的 LINUX 系统一般都此默认情况),那么可以不要 -I 和 -L 两个选项,简单的如下使用:beyes@linux-beyes:~/C/thread> gcc -D_REENTRANT thread1.c -o thread1.exe -lpthread
运行及输出:beyes@linux-beyes:~/C/thread> ./thread1.exe
Waiting for thread to finish...
thread_function is running. Argument was Hello World
Thread joined, it returen Thank you for the CPU time
Message is now Bye!
分析与说明:
使用 pthread_create() 函数创建了新进程。在 pthread_create() 函数中,第一个参数 a_thread 是pthread_t 类型的指针,也就是指向创建完线程后的线程标识符。这个标识符在后面的函数如 pthread_join()中也会被当作参数来用到。pthread_create() 的第 2 个参数是线程属性,这里留空表示使用默认属性;第 3个参数表示线程创建成功后要开始执行的函数(线程);第 4 个参数是要传递给线程函数的参数。
在主函数,也可以认为是原始线程中,检测到新的线程已经被创建并启动,那么就需要调用 pthread_join() 来检测及等待新线程的状态,这跟进程里的 wait() 功能类似。加入不用 pthread_join(),那么线程函数无法成功执行,那么它会输出:Waiting for thread to finish...
Thread joined, it returen U(乱码)
Message is now Hello World 由输出可见,线程函数并没有得到执行。
在 pthread_join() 函数中,第一个参数就是由 ptread_create() 函数中返回给其第一个参数的线程标识符。第 2 个参数是个指针的指针,指向线程函数的结果---这个结果是由 pthread_exit() 中的参数带回来的。
另外,可以看到线程实际上是共享了主进程的全局变量的;如果是创建子进程,那么是对全局变量的一个拷贝,像上面程序中的 hello world 是无法被修改为 bye 的。 |
|