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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值