Linux中的并发:临界区中两个线程的交替访问

时间:2016-04-22 17:03:10

标签: linux multithreading concurrency semaphore

我是Linux中并发和线程概念的新手,我试图解决一个相对简单的问题。我创建了两个线程,它们运行相同的函数来递增全局变量。我真正希望从我的程序中添加该变量,即在每一步中增加该变量的线程在屏幕上打印一条消息,因此预期的输出应如下所示:

Thread 1 is incrementing variable count... count = 1
Thread 2 is incrementing variable count... count = 2
Thread 1 is incrementing variable count... count = 3
Thread 2 is incrementing variable count... count = 4

等等。

我尝试了一个信号量的实现,它确保了互斥,但结果却类似于:

Thread 2 is incrementing variable count... count = 1
Thread 2 is incrementing variable count... count = 2
Thread 2 is incrementing variable count... count = 3
Thread 2 is incrementing variable count... count = 4
Thread 2 is incrementing variable count... count = 5
Thread 1 is incrementing variable count... count = 6
Thread 1 is incrementing variable count... count = 7
Thread 1 is incrementing variable count... count = 8
Thread 1 is incrementing variable count... count = 9
Thread 1 is incrementing variable count... count = 10

我的代码如下:

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

int count = 0;
sem_t mutex;

void function1(void *arg)
{
        int i = 0;
        int *a = (int*) arg;

        while (i < 10)
        {
           sem_wait(&mutex);
           count++;
           i++;
           printf("From the function : %d count is %d\n",*a,count);
           sem_post(&mutex);
        }
}

int main()
{
    pthread_t t1,t2;
    int a = 1;
    int b = 2;
    pthread_create(&t1,NULL,(void *)function1,&a);
    pthread_create(&t2,NULL,(void *)function1,&b);

    sem_init(&mutex,0,1);
    pthread_join(t2,NULL);
    pthread_join(t1,NULL);
    sem_destroy(&mutex);
    return 0;
}

我现在的大问题是,如何在线程之间实现这种交替?我互相排斥,但仍然缺少交替。也许我对信号量的使用缺乏了解,但如果有人向我解释,我会非常感激。 (我已经阅读了几个关于这个主题的课程,即Linux信号量,并发和线程,但信息不够令人满意)

1 个答案:

答案 0 :(得分:0)

Mutex锁定不保证任何公平性。这意味着如果线程1释放它然后再次尝试获取它,则无法保证它不会 - 它只是保证在该块中不能同时运行两段代码。

编辑: 删除了之前的C风格解决方案,因为它可能不正确。该问题要求提供同步解决方案。

如果你真的想要这样做,你会使用一种叫做监视器和一个警卫(或条件变量)的东西。我不太熟悉C和pThreads所以你需要看看如何用它来做,但在Java中它看起来像:

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
String packageName = componentInfo.getPackageName();