linux操作系統編程——線程的應用

程序功能:

       程序分成兩個部分,一個寫端一個讀端,採用fifo進行進程間的通信,寫端負責寫入命令,讀端負責讀命令,讀端採用多線程的方式進行編寫程序,創建兩個線程,一個喚醒線程用於喚醒發送線程,一個發送線程用於發送消息;主線程讀取命令後,將命令添加到任務隊列中,喚醒線程進行判斷,如果任務隊列爲空則睡眠,否則喚醒發送線程,採用條件變量與互斥鎖進行線程間的同步互斥;


程序如下:

(1)、pthread_read.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <fcntl.h>

struct node
{
    int cmd;
    struct node *next;
};

struct node *head;
char buf[100];

pthread_mutex_t send_mutex, wake_mutex;
pthread_cond_t send_cond, wake_cond;

struct node *create_list(void);
void insert_list(struct node *, int );
void delete_list(struct node *, int );
int is_empty_list(struct node *);
int get_list_cmd(struct node *);

void *wake_func(void *);
void *send_func(void *);

int main(int argc, const char *argv[])
{
    pthread_t wake_pthread, send_pthread;
    int err;
    int fifo_fd;
    char cmd_buf[20];

    if (argc < 2)
    {
        fprintf(stderr, "usages: %s filename\n", argv[0]);
        exit(-1);
    }

    head = create_list();

    if ((fifo_fd = open(argv[1], O_RDONLY)) < 0)
    {
        perror("failed to open fifo");
        exit(-1);
    }

    err = pthread_create(&wake_pthread, NULL, wake_func, NULL);
    if (err < 0)
    {
        perror("failed to create wake_pthread");
        exit(-1);
    }

    err = pthread_create(&send_pthread, NULL, send_func, NULL);
    if (err < 0)
    {
        perror("failed to create send_pthread");
        exit(-1);
    }

    err = pthread_mutex_init(&wake_mutex, NULL);
    if (err < 0)
    {
        perror("failed to init wake_mutex");
        exit(-1);
    }

    err = pthread_mutex_init(&send_mutex, NULL);
    if (err < 0)
    {
        perror("failed to init send_mutex");
        exit(-1);
    }

    err = pthread_cond_init(&wake_cond, NULL);
    if (err < 0)
    {
        perror("failed to init wake_cond");
        exit(-1);
    }

    err = pthread_cond_init(&send_cond, NULL);
    if (err < 0)
    {
        perror("failed to init send_cond");
        exit(-1);
    }

    while(1)
    {
        read(fifo_fd, cmd_buf, sizeof(cmd_buf));

        if(strncmp(cmd_buf, "quit", 4) == 0)
            break;

        insert_list(head, atoi(cmd_buf));

        pthread_mutex_lock(&wake_mutex);
        pthread_cond_signal(&wake_cond);
        pthread_mutex_unlock(&wake_mutex);
    }

    return 0;
}

struct node *create_list(void)
{
    struct node *head;

    head = (struct node *)malloc(sizeof(struct node));
    head->next = NULL;

    return head;
}

void insert_list(struct node *head, int cmd)
{
    struct node *new;

    new = (struct node *)malloc(sizeof(struct node));
    new->cmd = cmd;

    new->next = head->next;
    head->next = new;

    return ;
}

void delete_list(struct node *head, int cmd)
{
    struct node *p = head->next;
    struct node *q = head;

    while (p != NULL)
    {
        if (p->cmd == cmd)
            break;
        
        p = p->next;
        q = q->next;
    }

    q->next = p->next;
    p->next = NULL;
    free(p);

    return ;
}

int is_empty_list(struct node *head)
{
    int value;

    if (head->next == NULL)
        value = 1;
    else
        value = 0;

    return value;
}

int get_list_cmd(struct node *head)
{
    struct node *p = head->next;

    return p->cmd;
}

void *wake_func(void *arg)
{
    int cmd;

    while (1)
    {
        pthread_mutex_lock(&wake_mutex);

        if (is_empty_list(head))
            pthread_cond_wait(&wake_cond, &wake_mutex);
        
        cmd = get_list_cmd(head);

        printf("cmd : %d\n", cmd);

        switch(cmd)
        {
            case 1:
                strcpy(buf, "fire is coming");
                pthread_cond_signal(&send_cond);
                delete_list(head, cmd);
                break;

            case 2:
                strcpy(buf, "thief is coming");
                pthread_cond_signal(&send_cond);
                delete_list(head, cmd);
                break;

            case 3:
                strcpy(buf, "take photos");
                pthread_cond_signal(&send_cond);
                delete_list(head, cmd);
                break;

            default:
                delete_list(head, cmd);
                break;
        }

        pthread_mutex_unlock(&wake_mutex);
    }

    return ;
}

void *send_func(void *arg)
{
    while(1)
    {
        pthread_mutex_lock(&send_mutex);
        pthread_cond_wait(&send_cond, &send_mutex);
        pthread_mutex_unlock(&send_mutex);
        
        printf("recv: %s\n", buf);
    }

    return ;
}

(2)write_fifo.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

int main(int argc, const char *argv[])
{
    int fifo_fd;
    char buf[20];

    if (argc < 2)
    {
        fprintf(stderr, "usages: %s fifo\n", argv[0]);
        exit(-1);
    }

    if (mkfifo(argv[1], 0666 | O_CREAT | O_EXCL) < 0)
    {
        if (errno == EEXIST)
        {
            if (mkfifo(argv[1], 0666) < 0)
            {
                perror("failed to create fifo");
                exit(-1);
            }
        }
    }

    if ((fifo_fd = open(argv[1], O_WRONLY)) < 0)
    {
        perror("failed to open fifo");
        exit(-1);
    }

    while(1)
    {
        printf(">");
        fgets(buf, sizeof(buf), stdin);
        buf[strlen(buf) - 1] = 0;

        write(fifo_fd, buf, strlen(buf) + 1);

        if(strncmp(buf, "quit", 4) == 0)
            break;
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章