多线程程序中的stdio同步
来源:互联网 发布:html class属性 数据库 编辑:程序博客网 时间:2024/05/19 19:32
在多线程程序中,stdio文件描述符是被各个线程共享的。如果多个线程需要进行stdio操作,那么stdio同步就是一个值得关注的问题了。为了实现stdio线程安全,flockfile和funlockfile调用就显得非常重要了。在很多的情况下,一些stdio操作以不被中断的顺序是非常重要的。
下面的程序就是一个多线程调用stdio操作的例子,每个线程都试图使用stdio实现命令行读写,但是输入输出设备是唯一的。我们可以把prompt_routine()中的一次输出操作(printf)和一次读操作(fgets)看做一次事务。根据事务的特性,每次事务都是应该原子性的完成。如果没有flockfile和funlockfile调用,就可能出现如下的状况:一号线程printf调用完成之后被挂起(这是非常有可能的,printf会产生一次系统调用,这很可能会导致一次新的进程调度),然后二号线程占用了CPU,它顺利地执行了一次printf和fgets。这样的效果就是非常混乱的,用户明明在和一号线程交互,却莫名其秒地冲出一个二号线程(大哥,你小三吧!)。
/* * flock.c * * Demonstrate use of stdio file locking to generate an "atomic" * prompting sequence. The write to stdout and the read from * stdin cannot be separated. */#include <pthread.h>#include "errors.h"/* * This routine writes a prompt to stdout (passed as the thread's * "arg"), and reads a response. All other I/O to stdin and stdout * is prevented by the file locks until both prompt and fgets are * complete. */void *prompt_routine (void *arg){ char *prompt = (char*)arg; char *string; int len; string = (char*)malloc (128); if (string == NULL) errno_abort ("Alloc string"); flockfile (stdin); flockfile (stdout); printf (prompt); if (fgets (string, 128, stdin) == NULL) string[0] = '\0'; else { len = strlen (string); if (len > 0 && string[len-1] == '\n') string[len-1] = '\0'; } funlockfile (stdout); funlockfile (stdin); return (void*)string;}int main (int argc, char *argv[]){ pthread_t thread1, thread2, thread3; char *string; int status;#ifdef sun /* * On Solaris 2.5, threads are not timesliced. To ensure * that our threads can run concurrently, we need to * increase the concurrency level. */ DPRINTF (("Setting concurrency level to 4\n")); thr_setconcurrency (4);#endif status = pthread_create ( &thread1, NULL, prompt_routine, "Thread 1> "); if (status != 0) err_abort (status, "Create thread"); status = pthread_create ( &thread2, NULL, prompt_routine, "Thread 2> "); if (status != 0) err_abort (status, "Create thread"); status = pthread_create ( &thread3, NULL, prompt_routine, "Thread 3> "); if (status != 0) err_abort (status, "Create thread"); status = pthread_join (thread1, (void**)&string); if (status != 0) err_abort (status, "Join thread"); printf ("Thread 1: \"%s\"\n", string); free (string); status = pthread_join (thread2, (void**)&string); if (status != 0) err_abort (status, "Join thread"); printf ("Thread 1: \"%s\"\n", string); free (string); status = pthread_join (thread3, (void**)&string); if (status != 0) err_abort (status, "Join thread"); printf ("Thread 1: \"%s\"\n", string); free (string); return 0;}问题:为什么各个线程之间不会形成死锁?在第三章中有过明确的说明,多临界资源情况下避免死锁的两种常见方法:
1.各个线程以固定的顺序对资源加锁
2.试加锁和退回
在本例中,各个线程运行的代码都是prompt_routine(),相当于使用了第一种方法,所以不会形成死锁。
0 0
- 多线程程序中的stdio同步
- Boost.Aiso教程 5-同步多线程程序中的处理程序
- Java多线程同步程序
- 多线程中的线程同步
- 多线程中的同步
- #include<stdio.h>在C程序中的作用
- 多线程中的lua同步问题
- servlet中的多线程同步问题
- 多线程同步中的门道(一)
- Java中的多线程与同步
- 多线程中的lua同步问题
- 多线程中的lua同步问题
- stdio.h中的幽默
- Visual Stdio中的断点
- Winform 程序中的多线程.
- Java 程序中的多线程
- Java 程序中的多线程
- Java 程序中的多线程
- Magento开发文档(一):Magento入门
- jwplayer页面上播放mp3
- Unity之自带shader
- 当你选择追求,就无须在意眼前小利。
- 简单工厂模式PK工厂方法模式
- 多线程程序中的stdio同步
- trap in shell
- Js也有console对象,在控制台打印调试再好不过
- iOS线程术语0.0
- Windows远程桌面连接Mac OS X
- DIV CSS display (block none inline)属性的用法教程
- hadooop 常用命令
- 不要温和地走进那个良夜!
- Ruby on Rails技术(五)——类与对象