歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux編程練習(一)—— 多線程+共享內存+線程信號量練習

在Ubuntu 12.04下的共享內存+多線程+信號量練習實例。

問題:程序要求用多線程+共享內存+信號量,實現將一個文件中的內容寫入到另一個空白文件中(讀與寫的操作必須分在兩個線程中完成),要求文件內容的大小要遠大於所用共享內存的大小。

分析:題目要求將一個文件(假設為in)中的數據存入到另一個空白文件(假如為out)中,而且要求共享內存的大小要小於文件傳輸內容的大小,因此我們就需要利用有限大小的共享內存和文件指針將in中的數據循環多次倒入到out文件中,而為了解決重復寫入或是漏寫等線程調度混亂造成的問題,需要在其中使用信號量加以同步控制。

具體實現如下:

/*********************
* 共享內存+多線程+線程信號量 應用例子
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>

sem_t bin_sem; //信號量
int end_flag;  //結束標志符
char *sh_ptr;

/* 向out文件中寫數據 */
void* Tid_write(void *a)
{
    FILE *fp;
 fp = fopen("out", "w");
        while(end_flag)
 {
  sem_wait(&bin_sem);
  if(sh_ptr[0] != 0)
  {
   fprintf(fp, "%s", sh_ptr);
   memset(sh_ptr, 0, sizeof(sh_ptr));
  }
  sem_post(&bin_sem);
 }
    fclose(fp);
    return (void*)0;
}

/* 從in文件中讀數據 */
void *Tid_read(void *arg)
{
 FILE *fp;
 fp = fopen("in", "r");
        while(!feof(fp))
 {
  sem_wait(&bin_sem);
  if(sh_ptr[0] == 0)
  {
      fgets(sh_ptr, 10, fp);
            //printf("(%s)\n", sh_ptr);
        }
  sem_post(&bin_sem);
 }
 fclose(fp);
 end_flag = 0;
    return (void *)0;
}

int main()
{
    int shm_id;
    end_flag = 1;
    pthread_t tid_1, tid_2;
    int err_0, err_1, err_2;

    shm_id = shmget(IPC_PRIVATE, 15, IPC_CREAT|0600); //建立共享內存
    if(shm_id == -1)
    {
        fprintf(stderr, "error");
        return 0;
    }
    sh_ptr = (char *)shmat(shm_id, NULL, 0);
    memset(sh_ptr, 0, sizeof(sh_ptr));

    err_0 = sem_init(&bin_sem, 0, 1);// 初始化信號量
    if(err_0 < 0)
 fprintf(stderr, "sem_init error!");

    err_1 = pthread_create(&tid_1, NULL, Tid_write, NULL);
    err_2 = pthread_create(&tid_2, NULL, Tid_read, NULL);

    if(err_1!=0 || err_2!=0)
        fprintf(stderr, "pthread error!");

    pthread_join(tid_1, NULL);
    pthread_join(tid_2, NULL);
    shmdt(sh_ptr); //解除共享內存綁定
    sem_destroy(&bin_sem);//釋放信號量
    printf("project is over!\n");
    return 0;
}

Copyright © Linux教程網 All Rights Reserved