Linux下多线程实例

5 篇文章 0 订阅
3 篇文章 0 订阅

mydef.h

#include <semaphore.h>
#include <errno.h>
#ifdef Solaris
#include <thread.h>
#include <synch.h>
#endif
#ifdef Linux
#include <pthread.h>
#endif
#define MY_ERROR(thread,func) \
{\
    printf("Error in thread\"%s\",func=\"%s\",errno=%d\n",thread,func,errno);\
}
#define MY_ERROR2(thread,func,rt) \
{\
    printf("Error in thread\"%s\",func=\"%s\",return=%d,errno=%d\n",thread,func,rt,errno);\
}

typedef struct param_tag{
#ifdef Linux
    sem_t *sema1_p;
    sem_t *sema2_p;
#else
    sema_t *sema1_p;
    sema_t *sema2_p;
#endif
}param_t;

extern void * t1(void * p);
extern void * t2(void * p);
extern void * t3(void * p);
extern void * t4(void * p);
extern void * t5(void * p);
extern void * myhandle(int sig);
#ifdef Linux
extern sem_t sema1;
extern sem_t sema2;
#else
extern sema_t sema1;
extern sema_t sema2;
#endif

mytest.c

/** main thread
 *
 *       init  semaphore
 *       start thread 1
 *       start thread 2
 *       start thread 3
 *
 **/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include "mydef.h"

#ifdef Linux
    sem_t sema1;
    sem_t sema2;
#else
    sema_t sema1;
    sema_t sema2;
#endif
/** test deadlock
 *
 *       init  semaphore
 *       start thread 1
 *       start thread 2
 *       start thread 3
 *
 **/
int test_dlock()
{
#ifdef Linux
    pthread_t threadid;
#else
    thread_t threadid;
#endif
    param_t param;
    int rc;

#ifdef Linux
    rc = sem_init(&sema1,0,1);
    rc = sem_init(&sema2,0,1);
#else
    rc = sema_init(&sema1,1,USYNC_THREAD,NULL);
    rc = sema_init(&sema2,1,USYNC_THREAD,NULL);
#endif
    if( rc != 0 ) {
        MY_ERROR("main","sem_init")
        return 0;
    }
    
    param.sema1_p = &sema1;
    param.sema2_p = &sema2;
    
#ifdef Linux
    rc = pthread_create( &threadid, NULL, t1, (void *)¶m);
    if( rc != 0 ) {
        MY_ERROR("t1","pthread_create")
        return 0;
    }
    rc = pthread_create( &threadid, NULL, t2, (void *)¶m);
    rc = pthread_create( &threadid, NULL, t3, (void *)¶m);
#else
    rc = thr_create(NULL,0,t1, (void *)¶m,THR_BOUND,&threadid);
    if( rc != 0 ) {
        MY_ERROR("t1","thr_create")
        return 0;
    }
    rc = thr_create(NULL,0,t2, (void *)¶m,THR_BOUND,&threadid);
    rc = thr_create(NULL,0,t3, (void *)¶m,THR_BOUND,&threadid);
#endif
    sleep(5);
}
/** test EINTR
 *
 *       init  semaphore
 *       start thread 4
 *       start thread 5
 *
 **/
int test_intr()
{
#ifdef Linux
    pthread_t threadid;
#else
    thread_t threadid;
#endif
    param_t param;
    int rc;

#ifdef Linux
    rc = sem_init(&sema1,0,1);
    rc = sem_init(&sema2,0,1);
#else
    rc = sema_init(&sema1,1,USYNC_THREAD,NULL);
    rc = sema_init(&sema2,1,USYNC_THREAD,NULL);
#endif
    if( rc != 0 ) {
        MY_ERROR("main","sem_init")
        return 0;
    }
    
    signal(SIGSYS,myhandle);
    
    param.sema1_p = &sema1;
    param.sema2_p = &sema2;
#ifdef Linux
    rc = pthread_create( &threadid, NULL, t4, (void *)¶m);
    if( rc != 0 ) {
        MY_ERROR("t4","pthread_create")
        return 0;
    }
    rc = pthread_create( &threadid, NULL, t5, (void *)¶m);
#else
    rc = thr_create(NULL,0,t4, (void *)¶m,THR_BOUND,&threadid);
    if( rc != 0 ) {
        MY_ERROR("t4","thr_create")
        return 0;
    }
    rc = thr_create(NULL,0,t5, (void *)¶m,THR_BOUND,&threadid);
#endif
    sleep(100);
    return 0;
}
/** test EINTR single thread
 *
 *       init  semaphore
 *       t4()
 *
 **/
int test_intr_single()
{
    param_t param;
    int rc;

#ifdef Linux
    rc = sem_init(&sema1,0,1);
#else
    rc = sema_init(&sema1,1,USYNC_THREAD,NULL);
#endif
    if( rc != 0 ) {
        MY_ERROR("main","sem_init")
        return 0;
    }
    
    param.sema1_p = &sema1;
    param.sema2_p = NULL;
    t4(¶m);
    return 0;
}
int main()
{
    test_intr_single();
}

t1.c

/** thread 1
 *
 *       sem_wait(lock1)
 *       sleep(1)
 *       sem_wait(lock2)
 *       deadLock with t2   !!!
 *
 *
 **/
 
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "mydef.h"
extern void * t1(void * p)
{
#ifdef Linux
    sem_t *sema1_p;
    sem_t *sema2_p;
#else
    sema_t *sema1_p;
    sema_t *sema2_p;
#endif
    param_t *param_p = p;
    int rc;
    int val;

    sema1_p = param_p->sema1_p;
    sema2_p = param_p->sema2_p;
    
#ifdef Linux
    rc = sem_wait(sema1_p);
#else
    rc = sema_wait(sema1_p);
#endif
    if( rc != 0 ) {
        MY_ERROR("t1","sema_wait(sema1)")
        return 0;
    }
    printf("thread \"t1\" get \"sema1\" OK.\n");
#ifdef Linux
    rc = sem_getvalue(sema1_p, &val);
    printf("thread \"t1\" value of \"sema1\" is %d.\n", val);
#endif
    sleep(1);
#ifdef Linux
    rc = sem_getvalue(sema2_p, &val);
    printf("thread \"t1\" value of \"sema2\" is %d.\n", val);
#endif
    printf("thread \"t1\" waiting for \"sema2\" ...\n");
#ifdef Linux
    rc = sem_wait(sema2_p);
#else
    rc = sema_wait(sema2_p);
#endif
    if( rc != 0 ) {
        MY_ERROR("t1","sema_wait(sema2)")
        return 0;
    }
    printf("thread \"t1\" get \"sema2\" OK.\n");
    return 0;
}

t2.c

/** thread 2
 *
 *       sem_wait(lock2)
 *       sleep(1)
 *       sem_wait(lock1)
 *       deadLock with t1  !!!
 *
 *
 **/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "mydef.h"
extern void * t2(void * p)
{
#ifdef Linux
    sem_t *sema1_p;
    sem_t *sema2_p;
#else
    sema_t *sema1_p;
    sema_t *sema2_p;
#endif
    param_t *param_p = p;
    int rc;
    int val;

    sema1_p = param_p->sema1_p;
    sema2_p = param_p->sema2_p;
    
#ifdef Linux
    rc = sem_wait(sema2_p);
#else
    rc = sema_wait(sema2_p);
#endif
    if( rc != 0 ) {
        MY_ERROR("t2","sema_wait(sema2)")
        return 0;
    }
    printf("thread \"t2\" get \"sema2\" OK.\n");
#ifdef Linux
    rc = sem_getvalue(sema2_p, &val);
    printf("thread \"t2\" value of \"sema2\" is %d.\n", val);
#endif
    sleep(1);
#ifdef Linux
    rc = sem_getvalue(sema1_p, &val);
    printf("thread \"t2\" value of \"sema1\" is %d.\n", val);
#endif
    printf("thread \"t2\" waiting for \"sema1\" ...\n");
#ifdef Linux
    rc = sem_wait(sema1_p);
#else
    rc = sema_wait(sema1_p);
#endif
    if( rc != 0 ) {
        MY_ERROR("t2","sema_wait(sema1)")
        return 0;
    }
    printf("thread \"t2\" get \"sema1\" OK.\n");
    return 0;
}

t3.c

/** thread 3
 *
 *       sleep(3)
 *       sem_trywait(lock1)
 *       deteck deadLock between t1 and t2
 *
 **/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "mydef.h"
extern void * t3(void * p)
{
#ifdef Linux
    sem_t *sema1_p;
    sem_t *sema2_p;
#else
    sema_t *sema1_p;
    sema_t *sema2_p;
#endif
    param_t *param_p = p;
    int rc;
    int val;

    sema1_p = param_p->sema1_p;
    sema2_p = param_p->sema2_p;
    
    sleep(3);
    errno = -1;
#ifdef Linux
    rc = sem_trywait(sema1_p);
    if( rc == -1 ) {
        switch(errno)
        {
            case EBUSY:
                printf("thread \"t3\" can't get \"sema1\" : EBUSY.\n");
                break;
            case EAGAIN:
                printf("thread \"t3\" can't get \"sema1\" : EAGAIN.\n");
                break;
            case EDEADLK:
                printf("thread \"t3\" can't get \"sema1\" : EDEADLK.\n");
                break;
            case EINTR:
                printf("thread \"t3\" can't get \"sema1\" : EINTR.\n");
                break;
            default:
                MY_ERROR2("t3","sema_trywait(sema1)",rc)
        }
        return 0;
    }
    if( rc != 0 ) {// for solaris librt.so
        switch(rc)
        {
            case EBUSY:
                printf("thread \"t3\" can't get \"sema1\" : EBUSY.\n");
                break;
            case EAGAIN:
                printf("thread \"t3\" can't get \"sema1\" : EAGAIN.\n");
                break;
            case EDEADLK:
                printf("thread \"t3\" can't get \"sema1\" : EDEADLK.\n");
                break;
            case EINTR:
                printf("thread \"t3\" can't get \"sema1\" : EINTR.\n");
                break;
            default:
                MY_ERROR2("t3","sema_trywait(sema1)",rc)
        }
        return 0;
    }
#else
    rc = sema_trywait(sema1_p);
    if( rc != 0 ) {
        switch(rc)
        {
            case EBUSY:
                printf("thread \"t3\" can't get \"sema1\" : EBUSY.\n");
                break;
            case EAGAIN:
                printf("thread \"t3\" can't get \"sema1\" : EAGAIN.\n");
                break;
            case EDEADLK:
                printf("thread \"t3\" can't get \"sema1\" : EDEADLK.\n");
                break;
            case EINTR:
                printf("thread \"t3\" can't get \"sema1\" : EINTR.\n");
                break;
            default:
                MY_ERROR("t3","sema_trywait(sema1)")
        }
        return 0;
    }
#endif
    printf("thread \"t3\" get \"sema1\" OK.\n");
    return 0;
}

t4.c

/** thread 4
 *
 *       loop:   usleep(100000);sem_trywait(sema1);sem_post(sema1);
 *       deteck EINTR in sem_trywait()
 *
 **/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "mydef.h"
extern void * t4(void * p)
{
#ifdef Linux
    sem_t *sema1_p;
    sem_t *sema2_p;
#else
    sema_t *sema1_p;
    sema_t *sema2_p;
#endif
    param_t *param_p = p;
    int rc;
    int val;

    sema1_p = param_p->sema1_p;
    sema2_p = param_p->sema2_p;
    
    while(1)
    {
        usleep(100000);
        errno = -1;
#ifdef Linux
    //rc = sem_getvalue(sema1_p, &val);
    //printf("thread \"t4\" value of \"sema1\" is %d.\n", val);
        rc = sem_trywait(sema1_p);
        //rc = sem_wait(sema1_p);
        if( rc == -1 ) {
            switch(errno)
            {
                case EBUSY:
                    printf("thread \"t4\" can't get \"sema1\" : EBUSY.\n");
                    break;
                case EAGAIN:
                    printf("thread \"t4\" can't get \"sema1\" : EAGAIN.\n");
                    break;
                case EDEADLK:
                    printf("thread \"t4\" can't get \"sema1\" : EDEADLK.\n");
                    break;
                case EINTR:
                    printf("thread \"t4\" can't get \"sema1\" : EINTR.\n");
                    break;
                default:
                    MY_ERROR2("t4","sema_trywait(sema1)",rc)
            }
        }
#else
        rc = sema_trywait(sema1_p);
        if( rc != 0 ) {
            switch(rc)
            {
                case EBUSY:
                    printf("thread \"t4\" can't get \"sema1\" : EBUSY.\n");
                    break;
                case EAGAIN:
                    printf("thread \"t4\" can't get \"sema1\" : EAGAIN.\n");
                    break;
                case EDEADLK:
                    printf("thread \"t4\" can't get \"sema1\" : EDEADLK.\n");
                    break;
                case EINTR:
                    printf("thread \"t4\" can't get \"sema1\" : EINTR.\n");
                    break;
                default:
                    MY_ERROR("t4","sema_trywait(sema1)")
            }
        }
#endif
#ifdef Linux
        rc = sem_post(sema1_p);
        if( rc == -1 ) {
            switch(errno)
            {
                case EBUSY:
                    printf("thread \"t4\" can't post \"sema1\" : EBUSY.\n");
                    break;
                case EAGAIN:
                    printf("thread \"t4\" can't post \"sema1\" : EAGAIN.\n");
                    break;
                case EDEADLK:
                    printf("thread \"t4\" can't post \"sema1\" : EDEADLK.\n");
                    break;
                case EINTR:
                    printf("thread \"t4\" can't post \"sema1\" : EINTR.\n");
                    break;
                default:
                    MY_ERROR2("t4","sem_post(sema1)",rc)
            }
        }
#else
        rc = sema_post(sema1_p);
        if( rc != 0 ) {
            switch(rc)
            {
                case EBUSY:
                    printf("thread \"t4\" can't post \"sema1\" : EBUSY.\n");
                    break;
                case EAGAIN:
                    printf("thread \"t4\" can't post \"sema1\" : EAGAIN.\n");
                    break;
                case EDEADLK:
                    printf("thread \"t4\" can't post \"sema1\" : EDEADLK.\n");
                    break;
                case EINTR:
                    printf("thread \"t4\" can't post \"sema1\" : EINTR.\n");
                    break;
                default:
                    MY_ERROR("t4","sema_post(sema1)")
            }
        }
#endif
    }
    return 0;
}

t5.c

/** thread 5
 *
 *       loop:   usleep(50000);raise(signum);
 *
 *       try EINTR in sem_trywait()
 *
 **/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include "mydef.h"
extern void * t5(void * p)
{
    while(1)
    {
        usleep(50000);
        raise(SIGSYS);
    }
    return 0;
}

extern void * myhandle(int sig)
{
    return 0;
}

cmp_linux.sh

#!/bin/sh
cc -c  -DLinux t1.c
cc -c  -DLinux t2.c
cc -c  -DLinux t3.c
cc -c  -DLinux t4.c
cc -c  -DLinux t5.c
cc -c  -DLinux mytest.c
cc -o mytest t1.o t2.o t3.o t4.o t5.o mytest.o -lpthread

cmp_sol.sh

#!/bin/sh
cc -c  -DSolaris t1.c
cc -c  -DSolaris t2.c
cc -c  -DSolaris t3.c
cc -c  -DSolaris t4.c
cc -c  -DSolaris t5.c
cc -c  -DSolaris mytest.c
cc -o mytest t1.o t2.o t3.o t4.o t5.o mytest.o -lpthread


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值