码迷,mamicode.com
首页 > 其他好文 > 详细

进程之互斥

时间:2014-08-25 22:44:25      阅读:310      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   os   io   for   ar   2014   

题目

共要卖票20张,由命令行输入窗口数,由线程模拟窗口。每卖掉一张票,屏幕显示由几号窗口所卖,一并显示剩余票数

思路

由于票数 ticket_cnt 是全局变量,因此每当一个线程将其减一(卖出一张票),并将其显示,应该被封装为一个原子操作。因为线程是并发执行的,可能当前线程将ticket_cnt减1后还没有来得及显示此时的剩余票数ticket_cnt,ticket_cnt已经被另一个线程减一了。此处通过互斥锁实现互斥。

函数原型

创建线程:

NAME
       pthread_create - create a new thread

SYNOPSIS
       #include <pthread.h>

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

       Compile and link with -pthread.

回收线程资源,该函数为阻塞函数。

NAME
       pthread_join - join with a terminated thread

SYNOPSIS
       #include <pthread.h>

       int pthread_join(pthread_t thread, void **retval);

       Compile and link with -pthread.

DESCRIPTION
       The  pthread_join() function waits for the thread specified
       by thread to terminate.  If that thread has already  termi-
       nated, then pthread_join() returns immediately.  The thread
       specified by thread must be joinable.

       If retval is not NULL, then pthread_join() copies the  exit
       status  of the target thread (i.e., the value that the tar-
       get thread supplied to pthread_exit(3)) into  the  location
       pointed  to by *retval.  If the target thread was canceled,
       then PTHREAD_CANCELED is placed in *retval.

       If multiple threads simultaneously try  to  join  with  the
       same  thread,  the  results  are  undefined.  If the thread
       calling pthread_join() is canceled, then the target  thread
       will remain joinable (i.e., it will not be detached).

RETURN VALUE
       On  success, pthread_join() returns 0; on error, it returns
       an error number.

解锁开锁

NAME
       pthread_mutex_lock
       pthread_mutex_unlock - lock and unlock a mutex

SYNOPSIS
       #include <pthread.h>

       int pthread_mutex_lock(pthread_mutex_t *mutex);
       int pthread_mutex_unlock(pthread_mutex_t *mutex);

初始化锁,销毁锁

NAME
       pthread_mutex_destroy,  pthread_mutex_init  -  destroy  and initialize a mutex

SYNOPSIS
       #include <pthread.h>

       int pthread_mutex_destroy(pthread_mutex_t *mutex);
       int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

代码

/*************************************************************************
  > File Name: ticket.c
  > Author: KrisChou
  > Mail:zhoujx0219@163.com 
  > Created Time: Mon 25 Aug 2014 07:40:38 PM CST
 ************************************************************************/

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

int ticket_cnt = 20;     /* 共有20张票 */
typedef struct tag
{
    int s_id;
    pthread_mutex_t *s_p;
}DATA,*pDATA;

void* handler(void *arg )
{
    int id = ((pDATA)arg)->s_id;
    pthread_mutex_t *p_mutex = ((pDATA)arg)-> s_p;
    printf("a window on !: %d \n", id);
    while(1)
    {
        pthread_mutex_lock(p_mutex);
        if(ticket_cnt == 0)
        {
            printf("ticket out! \n");
            pthread_mutex_unlock(p_mutex);
            free((pDATA)arg);
            return (void*)0;
        }
        --ticket_cnt;
        sleep(rand()%3 + 1);
        printf("window: %d : a ticket sold. left : %d \n", id,ticket_cnt );
        pthread_mutex_unlock(p_mutex);
        sleep(rand() % 3 + 1); /* 如果不sleep,锁会一直被这个执行完的线程所占据 */

    }
}

int main(int argc, char *argv[])
{
    srand(getpid());
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, NULL);
    int thd_cnt = atoi(argv[1]); /* 从命令行输入卖票窗口数 */
    pthread_t *tds = (pthread_t*)calloc(thd_cnt,sizeof(pthread_t));
    int index;
    for(index = 0; index < thd_cnt; index++ )
    {
        pDATA p = (pDATA)calloc(1,sizeof(DATA));
        p->s_id = index;
        p->s_p = &mutex;
        pthread_create(tds + index , NULL,handler,(void*)p);
    }
    printf("joining...\n");
    for(index = 0; index < thd_cnt; index++)
    {
        pthread_join(tds[index],NULL);
    }
    pthread_mutex_destroy(&mutex);
    return 0;
}

编译运行:

[purple@localhost review]$ gcc ticket.c -lpthread
[purple@localhost review]$ ./a.out 5
joining...
a window on !: 2
a window on !: 3
a window on !: 4
a window on !: 1
a window on !: 0
window: 2 : a ticket sold. left : 19
window: 3 : a ticket sold. left : 18
window: 4 : a ticket sold. left : 17
window: 1 : a ticket sold. left : 16
window: 0 : a ticket sold. left : 15
window: 2 : a ticket sold. left : 14
window: 3 : a ticket sold. left : 13
window: 4 : a ticket sold. left : 12
window: 1 : a ticket sold. left : 11
window: 0 : a ticket sold. left : 10
window: 2 : a ticket sold. left : 9
window: 3 : a ticket sold. left : 8
window: 4 : a ticket sold. left : 7
window: 1 : a ticket sold. left : 6
window: 0 : a ticket sold. left : 5
window: 2 : a ticket sold. left : 4
window: 3 : a ticket sold. left : 3
window: 4 : a ticket sold. left : 2
window: 1 : a ticket sold. left : 1
window: 0 : a ticket sold. left : 0
ticket out!
ticket out!
ticket out!
ticket out!
ticket out!

进程之互斥

标签:des   style   blog   color   os   io   for   ar   2014   

原文地址:http://www.cnblogs.com/jianxinzhou/p/3936012.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!