1. 演示一个例子,出现死锁,用strace debug得到

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

sem_t sem;

typedef struct _cal_
{
    int sum;
}CAL;
CAL cal;

void *calculate(void*arg)
{
    int i;
    int sum;
    for(i = 0; i < 100; i++)
    {
        cal.sum = cal.sum + i;
    }
    sem_post(&sem);
}

void *sum(void *arg)
{
    sem_wait(&sem);
    printf("the sum is %d\n",cal.sum);
}

void *times(void *arg)
{
    sem_wait(&sem);
    printf("the times is %d\n",cal.sum * cal.sum);
}

int main(void)
{
    int ret=-1;
    pthread_t th[3];
    sem_init(&sem,0,0);
    ret = pthread_create(&th[0],NULL,calculate,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    

    ret = pthread_create(&th[1],NULL,sum,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    

    ret = pthread_create(&th[1],NULL,times,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    

    pthread_join(th[0],NULL);
    pthread_join(th[1],NULL);
    pthread_join(th[2],NULL);
    return 0;
}
mprotect(0xb5d46000, 4096, PROT_NONE)   = 0
clone(child_stack=0xb6546464, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xb6546ba8, {entry_number:6, base_addr:0xb6546b40, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xb6546ba8) = 17181
futex(0xb6546ba8, FUTEX_WAIT, 17181, NULL

futex(0xb7533ba8, FUTEX_WAIT, 17204, NULLthe times is 4950
) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)

上述的log表明,该code出现死锁,FUTEX_WAIT....... 而且Core Dumped 虽然times is 9801结果出来。(一开始测试不出来)

 

2. 基于信号量的问题,需要进行优化和解决:

更新一版代码:

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

sem_t sem_cal;
sem_t sem_times;

typedef struct _cal_
{
    int sum;
}CAL;
CAL cal;

void *calculate(void*arg)
{
    int i;
    int sum;
    for(i = 0; i < 100; i++)
    {
        cal.sum = cal.sum + i;
    }
    sem_post(&sem_cal);
}

void *sum(void *arg)
{
    sem_wait(&sem_cal);
    printf("the sum is %d\n",cal.sum);
    sem_post(&sem_times);
}

void *times(void *arg)
{
    sem_wait(&sem_times);
    printf("the times is %d\n",cal.sum * cal.sum);
}

int main(void)
{
    int ret=-1;
    pthread_t th[3];
    sem_init(&sem_cal,0,0);
    sem_init(&sem_times,0,0);
    ret = pthread_create(&th[0],NULL,calculate,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    

    ret = pthread_create(&th[1],NULL,sum,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    

    ret = pthread_create(&th[1],NULL,times,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    

    pthread_join(th[0],NULL);
    pthread_join(th[1],NULL);
    pthread_join(th[2],NULL);
    return 0;
}

但是出现:

the sum is 4950
the times is 24502500
Segmentation fault (core dumped)

futex(0xb65afba8, FUTEX_WAIT, 17277, NULL) = -1 EAGAIN (Resource temporarily unavailable)
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault (core dumped)

此时出现段错误,但是结果都正常。

Resource temporarily unavailable 表明资源冲突

3. 跟着解决这个段错误的问题:

原来是 ret = pthread_create(&th[1],NULL,times,NULL);同一个线程ID。

(DUANG)

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

sem_t sem_cal;
sem_t sem_times;

typedef struct _cal_
{
    int sum;
}CAL;
CAL cal;

void *calculate(void*arg)
{
    int i;
    int sum;
    for(i = 0; i < 100; i++)
    {
        cal.sum = cal.sum + i;
    }
    sem_post(&sem_cal);
}

void *sum(void *arg)
{
    sem_wait(&sem_cal);
    printf("the sum is %d\n",cal.sum);
    sem_post(&sem_times);
}

void *times(void *arg)
{
    sem_wait(&sem_times);
    printf("the times is %d\n",cal.sum * cal.sum);
}

int main(void)
{
    int ret=-1;
    pthread_t th[3];
    sem_init(&sem_cal,0,0);
    sem_init(&sem_times,0,0);
    ret = pthread_create(&th[0],NULL,calculate,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    

    ret = pthread_create(&th[1],NULL,sum,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    

    ret = pthread_create(&th[2],NULL,times,NULL);
    if (ret != 0)
    {
        printf("Pthread_create failed\n");
        return -1;
    }                    


    pthread_join(th[0],NULL);
    pthread_join(th[1],NULL);
    pthread_join(th[2],NULL);
    return 0;
}

该博客的目的是:

1. 通过多个信号量去完成业务。

2. 信号量和互斥锁的区别下节分析。