分享
 
 
 

开始使用pthreads(2)Hello World

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

2.Hello World

既然形式做完了,那我们就开始吧。pthread_create函数创建一个新的线程。它有四个参数,一个线程变量或是线程的持有者,一个线程的属性,当线程开始执行时调用的函数,一个该函数的参数。比如:

pthread_t a_thread;

pthread_attr_t a_thread_attribute;

void thread_function(void *argument);

char *some_argument;

pthread_create( &a_thread, a_thread_attribute, (void *)&thread_function,

(void *) &some_argument);

一个线程的属性当前只指定了被使用的最小的堆栈大小。以后的线程属性可能会更有趣,但现在大多数的程序只要简单的使用默认的就行了,即把pthread_attr_default传入函数。与用UNIX的fork命令创建的进程会与父线程同时执行同一条指令不同,线程在指定的函数中开始它们的执行。理由十分简单;如果线程不在别处开始执行,会得到的结果是许多线程用相同的资源执行同一条指令。回想一下每个进程都有自己的资源,而线程共享它们。

既然我们知道了如何去创建线程,我们已为我们的第一个程序做好了准备。让我们设计一个在标准输出上

打印出"Hello World"的多线程的程序。首先我们需要两个线程变量和一个被新的线程调用并执行的函数。

我们也必须指定每个线程必须打印出不同的消息。一种方法是把两个单词分成两个不同的字符串并且给每个

线程一个不同的字符串当作它的"startup(启动)"参数。看一下下面的代码:

void print_message_function( void *ptr );

main()

{

pthread_t thread1, thread2;

char *message1 = "Hello";

char *message2 = "World";

pthread_create( &thread1, pthread_attr_default,

(void*)&print_message_function, (void*) message1);

pthread_create(&thread2, pthread_attr_default,

(void*)&print_message_function, (void*) message2);

exit(0);

}

void print_message_function( void *ptr )

{

char *message;

message = (char *) ptr;

printf("%s ", message);

}

注意一下print_message_function 的函数原型和在pthread_create 调用中message参数前的转换。这个程序通过调用pthread_create函数并传递启动参数"Hello"创建第一个线程;第二个线程通过"World"参数来创建。当第一个线程开始执行时它从带着"Hello"参数的print_message_function开始。它打印出"Hello"然后终止执行。当一个线程离开初始的函数它也终止了,所以第一个线程在打印出"Hello"后就终止了。当第二个线程开始执行并打印出"World"后也相应的终止了。虽然这个程序看起来很合理,但它有两个缺点。

第一个也是最重要的,线程并发的执行。因此不能保证第一个线程比第二个线程线到达printf函数。所以我们可能看到"World Hello"而不是"Hello World".还有更微妙的一点。注意被父线程的main函数调用的exit函数。如果父线程在两个子线程调用printf之前调用exit,就不会有输出被产生。这是因为exit函数退出了这个进程(释放了任务),因此终止了所有线程。任何线程,附线程或子线程,只要有一个调用了exit函数,所有的这个进程的线程都将终止。如果想明确的终止线程应调用pthread_exit函数。

因此我们的hello world小程序有两个竞争情形。exit调用的竞争和哪个子进程先调用printf的竞争。让我们

用一个不太安全的方法来调整这些竞争。因为我们希望每个子进程在父进程结束前完成执行,让我们

在父进程中插入一个延迟,这样会给子进程时间去执行printf。为了保证第一个子进程比第二个先执行printf

,我们在第二个pthread_create 调用前插入一个延迟。结果代码:

void print_message_function( void *ptr );

main()

{

pthread_t thread1, thread2;

char *message1 = "Hello";

char *message2 = "World";

pthread_create( &thread1, pthread_attr_default,

(void *) &print_message_function, (void *) message1);

sleep(10);

pthread_create(&thread2, pthread_attr_default,

(void *) &print_message_function, (void *) message2);

sleep(10);

exit(0);

}

void print_message_function( void *ptr )

{

char *message;

message = (char *) ptr;

printf("%s", message);

pthread_exit(0);

}

这段代码是否符合我们的目标了呢?并不是。依靠时间延迟来执行同步永远不是安全的。因为线程之间的

紧密耦合而诱使人们用不那么严格的态度去处理同步,但那是应该被避免的。这里的竞争情形与一个分布式的应用程序和一个共享的资源情况相同。这里资源就是标准输出而分布式的计算单元就是三个线程。线程一必须比线程而先用ptintf/stdout,而且他们必须在父线程退出之前做。

在我们尝试用延时来同步的另一面,我们又犯了另一个大错。sleep函数与exit函数一样是与整个进程相连

系的。如果一个线程调用了sleep函数,整个进程将休眠,也就是当进程休眠时所有的线程也休眠了。因此这与我们不调用sleep函数的结果一样,只不过程序多运行了20秒。当想延迟一个线程的合适函数是pthread_delay_np(np代表not portable)。比如,延迟一个线程2秒钟:

struct timespec delay;

delay.tv_sec = 2;

delay.tv_nsec = 0;

pthread_delay_np( &delay );

本节提及的函数:

pthread_create(), pthread_exit(), and pthread_delay_np().

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有