zoukankan      html  css  js  c++  java
  • open files

    /*
     *
     *   Copyright (c) International Business Machines  Corp., 2001
     *
     *   This program is free software;  you can redistribute it and/or modify
     *   it under the terms of the GNU General Public License as published by
     *   the Free Software Foundation; either version 2 of the License, or
     *   (at your option) any later version.
     *
     *   This program is distributed in the hope that it will be useful,
     *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     *   the GNU General Public License for more details.
     *
     *   You should have received a copy of the GNU General Public License
     *   along with this program;  if not, write to the Free Software
     *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     */
    
    /*
     * FILE        : openfile.c
     * DESCRIPTION : Create files and open simultaneously
     * HISTORY:
     *   03/21/2001 Paul Larson (plars@us.ibm.com)
     *     -Ported
     *   11/01/2001 Mnaoj Iyer (manjo@austin.ibm.com)
     *     - Modified.
     *     added #inclide <unistd.h>
     *
     */
    
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <unistd.h>
    
    #include "test.h"
    #include "usctest.h"
    
    char *TCID = "openfile01";    /* Test program identifier.    */
    int TST_TOTAL = 1;
    
    #define MAXFILES        32768
    #define MAXTHREADS      10
    
    /* Control Structure */
    struct cb {
        pthread_mutex_t m;
        pthread_cond_t init_cv;
        pthread_cond_t thr_cv;
        int thr_sleeping;
    } c;
    
    /* Global Variables */
    int numthreads = 10, numfiles = 10;
    int debug = 0;
    char *filename = "FILETOOPEN";
    
    void setup(void)
    {
        tst_tmpdir();
    }
    
    void cleanup(void)
    {
        tst_rmdir();
    
    }
    
    /* Procedures */
    void *threads(void *thread_id);
    
    /* **************************************************************************
     *                              MAIN PROCEDURE                            *
     ************************************************************************** */
    
    int main(int argc, char *argv[])
    {
        int i, opt, badopts = 0;
        FILE *fd;
        pthread_t th_id;
        char msg[80] = "";
        extern char *optarg;
    
        while ((opt = getopt(argc, argv, "df:t:h")) != EOF) {
            switch ((char)opt) {
            case 'd':
                debug = 1;
                break;
            case 'f':
                numfiles = atoi(optarg);
                if (numfiles <= 0)
                    badopts = 1;
                break;
            case 't':
                numthreads = atoi(optarg);
                if (numthreads <= 0)
                    badopts = 1;
                break;
            case 'h':
            default:
                printf("Usage: openfile [-d] -f FILES -t THREADS
    ");
                _exit(1);
            }
        }
        if (badopts) {
            printf("Usage: openfile [-d] -f FILES -t THREADS
    ");
            _exit(1);
        }
    
        setup();
    
        /* Check if numthreads is less than MAXFILES */
        if (numfiles > MAXFILES) {
            sprintf(msg, "%s
    Cannot use %d files", msg, numfiles);
            sprintf(msg, "%s, used %d files instead
    ", msg, MAXFILES);
            numfiles = MAXFILES;
        }
    
        /* Check if numthreads is less than MAXTHREADS */
        if (numthreads > MAXTHREADS) {
            sprintf(msg, "%s
    Cannot use %d threads", msg, numthreads);
            sprintf(msg, "%s, used %d threads instead
    ", msg, MAXTHREADS);
            numthreads = MAXTHREADS;
        }
    
        /* Create files */
        if ((fd = fopen(filename, "w")) == NULL) {
            tst_resm(TFAIL, "Could not create file");
            cleanup();
        }
    
        /* Initialize thread control variables, lock & condition */
        pthread_mutex_init(&c.m, NULL);
        pthread_cond_init(&c.init_cv, NULL);
        pthread_cond_init(&c.thr_cv, NULL);
        c.thr_sleeping = 0;
    
        /* Grab mutex lock */
        if (pthread_mutex_lock(&c.m)) {
            tst_resm(TFAIL, "failed to grab mutex lock");
            fclose(fd);
            unlink(filename);
            cleanup();
        }
    
        printf("Creating Reading Threads
    ");
    
        /* Create threads */
        for (i = 0; i < numthreads; i++)
            if (pthread_create(&th_id, (pthread_attr_t *) NULL, threads,
                       (void *)(uintptr_t) i)) {
                tst_resm(TFAIL,
                     "failed creating a pthread; increase limits");
                fclose(fd);
                unlink(filename);
                cleanup();
            }
    
        /* Sleep until all threads are created */
        while (c.thr_sleeping != numthreads)
            if (pthread_cond_wait(&c.init_cv, &c.m)) {
                tst_resm(TFAIL,
                     "error while waiting for reading threads");
                fclose(fd);
                unlink(filename);
                cleanup();
            }
    
        /* Wake up all threads */
        if (pthread_cond_broadcast(&c.thr_cv)) {
            tst_resm(TFAIL, "failed trying to wake up reading threads");
            fclose(fd);
            unlink(filename);
            cleanup();
        }
        /* Release mutex lock */
        if (pthread_mutex_unlock(&c.m)) {
            tst_resm(TFAIL, "failed to release mutex lock");
            fclose(fd);
            unlink(filename);
            cleanup();
        }
    
        tst_resm(TPASS, "Threads are done reading");
    
        fclose(fd);
        unlink(filename);
        cleanup();
        _exit(0);
    }
    
    /* **************************************************************************
     *                OTHER PROCEDURES                *
     ************************************************************************** */
    
    void close_files(FILE * fd_list[], int len)
    {
        int i;
        for (i = 0; i < len; i++) {
            fclose(fd_list[i]);
        }
    }
    
    /* threads: Each thread opens the files specified */
    void *threads(void *thread_id_)
    {
        int thread_id = (uintptr_t) thread_id_;
        char errmsg[80];
        FILE *fd_list[MAXFILES];
        int i;
    
        /* Open files */
        for (i = 0; i < numfiles; i++) {
            if (debug)
                printf("Thread  %d : Opening file number %d 
    ",
                       thread_id, i);
            if ((fd_list[i] = fopen(filename, "rw")) == NULL) {
                sprintf(errmsg, "FAIL - Couldn't open file #%d", i);
                perror(errmsg);
                if (i > 0) {
                    close_files(fd_list, i - 1);
                }
                unlink(filename);
                pthread_exit((void *)1);
            }
        }
    
        /* Grab mutex lock */
        if (pthread_mutex_lock(&c.m)) {
            perror("FAIL - failed to grab mutex lock");
            close_files(fd_list, numfiles);
            unlink(filename);
            pthread_exit((void *)1);
        }
    
        /* Check if you should wake up main thread */
        if (++c.thr_sleeping == numthreads)
            if (pthread_cond_signal(&c.init_cv)) {
                perror("FAIL - failed to signal main thread");
                close_files(fd_list, numfiles);
                unlink(filename);
                pthread_exit((void *)1);
            }
    
        /* Sleep until woken up */
        if (pthread_cond_wait(&c.thr_cv, &c.m)) {
            perror("FAIL - failed to wake up correctly");
            close_files(fd_list, numfiles);
            unlink(filename);
            pthread_exit((void *)1);
        }
    
        /* Release mutex lock */
        if (pthread_mutex_unlock(&c.m)) {
            perror("FAIL - failed to release mutex lock");
            close_files(fd_list, numfiles);
            unlink(filename);
            pthread_exit((void *)1);
        }
    
        /* Close file handles and exit */
        close_files(fd_list, numfiles);
        unlink(filename);
        pthread_exit((void *)0);
    }
  • 相关阅读:
    手撕 Goroutine 同步问题
    go基础知识面试备忘录
    专题3:链表类题型总结(go)
    python自动化开发-[第四天]-函数
    NOIP 飞扬的小鸟 题解
    集合 Properties 的 简单例子(Spring)
    Linux常用命令
    网络安全系列索引
    关于个人博客
    使用User Agent和代理IP隐藏身份
  • 原文地址:https://www.cnblogs.com/unixshell/p/3818759.html
Copyright © 2011-2022 走看看