在linux中调度两个线程两个打印数字模式

时间:2016-10-17 06:18:35

标签: c linux multithreading synchronization

我想使用两个帖子T1T2打印数字。 T1应打印1,2,3,4,5之类的数字,然后T2应打印6,7,8,9,10,然后T1应再次启动,然后应T2。它应该从1....100打印。我有两个问题。

  1. 如何使用线程和一个全局变量完成任务?
  2. 如何在linux中按所需顺序安排线程?

3 个答案:

答案 0 :(得分:1)

  

如何在linux中按所需顺序安排线程?

您需要使用锁定原语(例如互斥锁或条件变量)来影响线程的调度顺序。或者你必须让你的线程在订单上独立工作。

  

如何使用线程和一个全局变量完成任务?

如果允许只使用一个变量,则不能使用互斥锁(它将是第二个变量)。所以你必须做的第一件事就是声明你的变量原子。否则,编译器可能会以这样的方式优化您的代码:一个线程不会看到其他线程所做的更改。对于你想要的这样简单的代码,它将通过在寄存器上缓存变量来实现。使用std::atomic_int。您可以找到使用volatile int的建议,但现在std::atomic_int是一种更直接的方法来指定您想要的内容。

您不能使用互斥锁,因此无法让线程等待。它们将不断运行并浪费CPU。但这对任务来说似乎没问题。所以你需要写一个自旋锁。线程将在循环中等待不断检查值。如果value % 10 < 5则第一个线程中断循环并递增,否则第二个线程完成该任务。

因为问题看起来像是家庭作业,所以我不会在这里显示任何代码示例,您需要自己编写。

答案 1 :(得分:1)

1:最简单的方法是使用互斥锁。 这是一个带有不公平/未定义调度的基本实现

int counter=1;
pthread_mutex_t mutex; //needs to be initialised

void incrementGlobal() {
    for(int i=0;i<5;i++){
        counter++;
        printf("%i\n",counter);
    }
 }

T1 / T2:

pthread_mutex_lock(&mutex);
incrementGlobal();
pthread_mutex_unlock(&mutex);

2:使用条件变量可以达到正确的顺序: (但这需要更多的全局变量)

全局:

int num_thread=2;
int current_thread_id=0;
pthread_cond_t cond; //needs to be initialised

T1 / T2:

int local_thread_id; // the ID of the thread
while(true) {
    phread_mutex_lock(&mutex);
    while (current_thread_id != local_thread_id) {
        pthread_cond_wait(&cond, &mutex);
    }
    incrementGlobal();
    current_thread_id = (current_thread_id+1) % num_threads; 
    pthread_cond_broadcast(&cond);
    pthread_mutex_unlock(&mutex);
}

答案 2 :(得分:0)

  

如何使用线程和一个全局变量完成任务?

如果您使用Linux,则可以使用POSIX库在C编程语言中进行线程化。该库是<pthread.h>。但是,作为替代方案,在gccg++以及(使用旧版本)MSVC上得到良好支持的相当便携且相对非侵入性的库是openMP

它不是标准的C和C ++,但OpenMP本身就是标准。

  

如何在linux中按所需顺序安排线程?

要实现所需的打印操作,您需要有一个全局变量,可以由您的两个线程访问。两个线程轮流访问全局变量variable并执行操作(incrementprint)。但是,要实现desired order,您需要拥有mutex。互斥量是互斥信号量,是信号量的特殊变体,一次只允许一个锁定器。当您拥有资源实例(global variable in your case)并且该资源由两个线程共享时,可以使用它。锁定该互斥锁之后的一个线程可以拥有对资源实例的独占访问权,并且在完成它的操作之后,线程应该释放其他线程的互斥锁。

您可以从here<pthread.h>开始使用线程和互斥。

您问题的可能解决方案之一可能是此程序如下。但是,我建议你自己尝试一下然后看看我的解决方案。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t lock;
int variable=0;

#define ONE_TIME_INC 5
#define MAX 100

void *thread1(void *arg)
{
 while (1) {
    pthread_mutex_lock(&lock);
    printf("Thread1: \n");
    int i;
    for (i=0; i<ONE_TIME_INC; i++) {
        if (variable >= MAX)
            goto RETURN;
        printf("\t\t%d\n", ++variable);
    }   
    printf("Thread1: Sleeping\n");
    pthread_mutex_unlock(&lock);
    usleep(1000);
}
RETURN:
pthread_mutex_unlock(&lock);
return NULL;
}

void *thread2(void *arg)
{
while (1) {
    pthread_mutex_lock(&lock);
    printf("Thread2: \n");
    int i;
    for (i=0; i<ONE_TIME_INC; i++) {
        if (variable >= MAX)
            goto RETURN;
        printf("%d\n", ++variable);
    }   
    printf("Thread2: Sleeping\n");
    pthread_mutex_unlock(&lock);
    usleep(1000);
}
RETURN:
pthread_mutex_unlock(&lock);
return NULL;

}

int main()
{

if (pthread_mutex_init(&lock, NULL) != 0) {
    printf("\n mutex init failed\n");
    return 1;
}

pthread_t pthread1, pthread2;
if (pthread_create(&pthread1, NULL, thread1, NULL))
    return -1;
if (pthread_create(&pthread2, NULL, thread2, NULL))
    return -1;

pthread_join(pthread1, NULL);
pthread_join(pthread2, NULL);

pthread_mutex_destroy(&lock);

return 0;
}