在QNX Momentics环境中有几个样例供初学者参考,学习QNX多线程编程的一个好方法是导入QNX的多线程样例,测试运行后分析样例代码,和自己编写测试样例相比,这种方法可以减少输入错误,配置错误等低级错误带来的问题。
在QNX Momentics中选择“File->New -> Example...”打开样例向导,选择“QNX Example Neutrino Threads Project”。然后保留缺省设置,点击“Next”,“Finish”即可创建QNX多线程样例工程。
所创建的工程的目标系统是X86,所以在QNX虚拟机上不需要修改就可以运行,选择项目,点击右键并选择“Build Project”对项目进行编译。
编译成功后可以通过“Run As->Rung Configuration”配置运行环境,具体过程参考之前的博文。
运行成功后在控制台的输出如下,行号是我为了方便分析加进去的,各位同学请结合后面的代码分析部分阅读:
1: Creating thread now.
2: functionA active
3: Thread was created.
4: The main thread is going on...
5: ... as long as it hasn't used up its timeslice.
6: Creating another thread.
7: functionB is working...
8: Thread was created.
9: The main thread continues...
10: We are now creating two more threads...
11: universalthread is now running...
12: universalthread: localvariable 3 * parameter 12 = 36
13: universalthread is now running...
14: universalthread: localvariable 3 * parameter 59 = 177
15: Threads created.
16: Main thread now waiting for first thread to finish
17: universalthread: localvariable 15 * parameter 12 = 180
18: universalthread: localvariable 62 * parameter 59 = 3658
19: universalthread: localvariable 27 * parameter 12 = 324
20: universalthread: localvariable 121 * parameter 59 = 7139
21: functionA is finished.
22: Thread 2 completed its function!
23: Main thread now waiting for termination through user.
24: Other threads keep running in the background until
25: they finish or are terminated together with the main thread.
26: universalthread: localvariable 39 * parameter 12 = 468
27: universalthread: localvariable 180 * parameter 59 = 10620
28: functionB done.
29: universalthread: localvariable 51 * parameter 12 = 612
30: universalthread: localvariable 239 * parameter 59 = 14101
31: universalthread with parameter 12 finished.
32: universalthread with parameter 59 finished.
下面是对样例代码的分析,大家从中可以了解QNX中线程工作的基本过程。
#include
#include
#include
#include
#include
#include
//下面是对线程需要调用的方法的声明,之所以在这里声明是因为这些方法的定义在main方法后,
//而main方法需要调用它们,如果这里不做声明,在main方法中调用时会出错,编译过程就出错。
void *functionA();
void *functionB();
void *universalthread(int parameter);
//程序入口
int main () {
//定义线程ID变量,用于记录线程ID
pthread_tour_thread_id;
//控制台输出,对应上面控制台输出的第一行。
printf("Creating thread now.\n");
//创建一个线程,该线程调用functionA方法,线程ID会在our_thread_id中保存,注意参数中使用的是&our_thread_id
pthread_create(&our_thread_id, NULL, &functionA ,NULL);
//控制台输出,第3行。在此之前第2行已经输出了线程中的信息。
printf("Thread was created.\n");
//主线程继续运行,输出4,5行
printf("The main thread is going on...\n");
printf("... as long as it hasn't used up its timeslice.\n");
//输出第6行
printf("Creating another thread.\n");
//创建第二个线程,线程调用functionB方法
pthread_create(NULL,NULL, &functionB ,NULL);
//输出第8,9行,注意第7行输出是由子线程输出的。
printf("Thread was created.\n");
printf("The main thread continues...\n");
//控制台输出,第10行
printf("We are now creating two more threads...\n");
//再创建两个线程,注意参数的传递方式
pthread_create(NULL,NULL, (void *) &universalthread, (void *) 12);
pthread_create(NULL,NULL, (void *) &universalthread, (void *) 59);
//控制台输出,15行,从11到14行是由刚创建的两个线程输出的
printf("Threads created.\n");
//控制台输出,16行
printf("Main thread now waiting for first thread to finish\n");
//通过join方法等待第一个子线程结束,传入的是第一个子线程的线程ID
pthread_join(our_thread_id, NULL);
//控制台输出,22行,注意21行是第一个子线程输出的,第一个子线程结束后主线程才结束join方法
printf("Thread %d completed its function!\n",our_thread_id);
//控制台输出,23,24,25行
printf("Main thread now waiting for termination through user.\n");
printf("Other threads keep running in the background until\n");
printf("they finish or are terminated together with the main thread.\n");
//等待用户结束主线程(Ctrl+C ),此时其它子线程继续运行。
pause();
//主线程结束,返回
return EXIT_SUCCESS;
}
void *functionA()
{
printf("functionA active\n");
sleep(5);
printf ("functionA is finished.\n");
return(NULL);
}
void *functionB()
{
printf("functionB is working...\n");
sleep (7);
printf("functionB done.\n");
return(NULL);
}
void *universalthread(int parameter)
{
int localvariable;
int counter = 0;
localvariable = 3;
printf("universalthread is now running...\n");
while ( counter < 5) {
printf ("universalthread: localvariable %d * parameter %d = %d\n", localvariable, parameter, (localvariable * parameter));
localvariable = localvariable + parameter;
counter++;
sleep(2);
}
printf("universalthread with parameter %d finished.\n",parameter);
return(NULL);
}