国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Linux > 正文

Linux多線程之互斥

2024-06-28 13:24:33
字體:
供稿:網(wǎng)友
linux多線程之互斥題目

共要賣票20張,由命令行輸入窗口數(shù),由線程模擬窗口。每賣掉一張票,屏幕顯示由幾號窗口所賣,一并顯示剩余票數(shù)

思路

由于票數(shù) ticket_cnt 是全局變量,因此每當一個線程將其減一(賣出一張票),并將其顯示,應(yīng)該被封裝為一個原子操作。因為線程是并發(fā)執(zhí)行的,可能當前線程將ticket_cnt減1后還沒有來得及顯示此時的剩余票數(shù)ticket_cnt,ticket_cnt已經(jīng)被另一個線程減一了。此處通過互斥鎖實現(xiàn)互斥。

函數(shù)原型

創(chuàng)建線程:

NAME       pthread_create - create a new threadSYNOPSIS       #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.

回收線程資源,該函數(shù)為阻塞函數(shù)。

NAME       pthread_join - join with a terminated threadSYNOPSIS       #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 mutexSYNOPSIS       #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 mutexSYNOPSIS       #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,鎖會一直被這個執(zhí)行完的線程所占據(jù) */    }}int main(int argc, char *argv[]){    srand(getpid());    pthread_mutex_t mutex;    pthread_mutex_init(&mutex, NULL);    int thd_cnt = atoi(argv[1]); /* 從命令行輸入賣票窗口數(shù) */    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 5joining...a window on !: 2a window on !: 3a window on !: 4a window on !: 1a window on !: 0window: 2 : a ticket sold. left : 19window: 3 : a ticket sold. left : 18window: 4 : a ticket sold. left : 17window: 1 : a ticket sold. left : 16window: 0 : a ticket sold. left : 15window: 2 : a ticket sold. left : 14window: 3 : a ticket sold. left : 13window: 4 : a ticket sold. left : 12window: 1 : a ticket sold. left : 11window: 0 : a ticket sold. left : 10window: 2 : a ticket sold. left : 9window: 3 : a ticket sold. left : 8window: 4 : a ticket sold. left : 7window: 1 : a ticket sold. left : 6window: 0 : a ticket sold. left : 5window: 2 : a ticket sold. left : 4window: 3 : a ticket sold. left : 3window: 4 : a ticket sold. left : 2window: 1 : a ticket sold. left : 1window: 0 : a ticket sold. left : 0ticket out!ticket out!ticket out!ticket out!ticket out!
干貨

如果有一個整型參數(shù) a 需要在創(chuàng)建線程時將其傳遞給線程,那么以下兩種傳值方式,實際上是由區(qū)別的。來看代碼:

方式1:

void* handler(void *arg){    int val=*(int*)arg;    printf("from main: %d/n",val);    pthread_exit((void*)"hello world");}int main(){    pthread_t thd;    int a=12345;    pthread_create(&thd,NULL,handler,(void*)&a);    printf("thd: %x/n",thd);    pthread_join(thd,(void*)&ret);    return 0;}

方式2:

void* handler(void *arg){    int val=(int)arg;    printf("from main: %d/n",val);    pthread_exit((void*)"hello world");}int main(){    pthread_t thd;    int a=12345;    pthread_create(&thd,NULL,handler,(void*)a);    printf("thd: %x/n",thd);    pthread_join(thd,(void*)&ret);    return 0;}

對于方式1,傳給handler的參數(shù)是a的地址,如果a的值之后在主線程里會發(fā)生變化,那么傳給handler的數(shù)值a可能就不是原來我們想傳的那個了。

而對于方式2,由于是值傳遞,我們當時想傳什么,傳到handler中的就一定是什么。

由此可見,雖然方式1節(jié)省了存儲空間,但是同樣也容易發(fā)生錯誤。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 辽源市| 铜陵市| 栾川县| 永寿县| 兴业县| 江达县| 濮阳市| 汨罗市| 米林县| 麻栗坡县| 康乐县| 江门市| 上犹县| 化德县| 中卫市| 雷州市| 邛崃市| 湛江市| 玛多县| 乌拉特前旗| 洪江市| 乐山市| 肇庆市| 津市市| 陆川县| 金门县| 岐山县| 东明县| 瑞金市| 革吉县| 汤原县| 莱芜市| 彰化市| 泾川县| 屯留县| 梅州市| 潼关县| 城市| 昌邑市| 千阳县| 井研县|