同学的用多线程实现的监听键盘
在ubuntu12.04下的共享内存+多线程+信号量练习实例。
问题:程序要求用多线程+共享内存+信号量,实现将一个文件中的内容写入到另一个空白文件中(读与写的操作必须分在两个线程中完成),要求文件内容的大小要远大于所用共享内存的大小。
分析:题目要求将一个文件(假设为in)中的数据存入到另一个空白文 件(假如为out)中,而且要求共享内存的大小要小于文件传输内容的大小,因此我们就需要利用有限大小的共享内存和文件指针将in中的数据循环多次倒入到 out文件中,而为了解决重复写入或是漏写等线程调度混乱造成的问题,需要在其中使用信号量加以同步控制。
1 /********************* 2 * 共享内存+多线程+线程信号量 应用例子 3 */ 4 #include <stdio.h> 5 #include <string.h> 6 #include <stdlib.h> 7 #include <pthread.h> 8 #include <semaphore.h> 9 #include <sys/types.h> 10 #include <sys/shm.h> 11 #include <sys/ipc.h> 12 13 sem_t bin_sem; //信号量 14 int end_flag; //结束标志符 15 char *sh_ptr; 16 17 /* 向out文件中写数据 */ 18 void* Tid_write(void *a) 19 { 20 FILE *fp; 21 fp = fopen("out", "w"); 22 while(end_flag) 23 { 24 sem_wait(&bin_sem); 25 if(sh_ptr[0] != 0) 26 { 27 fprintf(fp, "%s", sh_ptr); 28 memset(sh_ptr, 0, sizeof(sh_ptr)); 29 } 30 sem_post(&bin_sem); 31 } 32 fclose(fp); 33 return (void*)0; 34 } 35 36 /* 从in文件中读数据 */ 37 void *Tid_read(void *arg) 38 { 39 FILE *fp; 40 fp = fopen("in", "r"); 41 while(!feof(fp)) 42 { 43 sem_wait(&bin_sem); 44 if(sh_ptr[0] == 0) 45 { 46 fgets(sh_ptr, 10, fp); 47 //printf("(%s)\n", sh_ptr); 48 } 49 sem_post(&bin_sem); 50 } 51 fclose(fp); 52 end_flag = 0; 53 return (void *)0; 54 } 55 56 int main() 57 { 58 int shm_id; 59 end_flag = 1; 60 pthread_t tid_1, tid_2; 61 int err_0, err_1, err_2; 62 63 shm_id = shmget(IPC_PRIVATE, 15, IPC_CREAT|0600); //建立共享内存 64 if(shm_id == -1) 65 { 66 fprintf(stderr, "error"); 67 return 0; 68 } 69 sh_ptr = (char *)shmat(shm_id, NULL, 0); 70 memset(sh_ptr, 0, sizeof(sh_ptr)); 71 72 err_0 = sem_init(&bin_sem, 0, 1);// 初始化信号量 73 if(err_0 < 0) 74 fprintf(stderr, "sem_init error!"); 75 76 err_1 = pthread_create(&tid_1, NULL, Tid_write, NULL); 77 err_2 = pthread_create(&tid_2, NULL, Tid_read, NULL); 78 79 if(err_1!=0 || err_2!=0) 80 fprintf(stderr, "pthread error!"); 81 82 pthread_join(tid_1, NULL); 83 pthread_join(tid_2, NULL); 84 shmdt(sh_ptr); //解除共享内存绑定 85 sem_destroy(&bin_sem);//释放信号量 86 printf("project is over!\n"); 87 return 0; 88 }