我想使用两个帖子T1
和T2
打印数字。 T1应打印1,2,3,4,5
之类的数字,然后T2应打印6,7,8,9,10
,然后T1
应再次启动,然后应T2
。它应该从1....100
打印。我有两个问题。
答案 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>
。但是,作为替代方案,在gcc
和g++
以及(使用旧版本)MSVC上得到良好支持的相当便携且相对非侵入性的库是openMP。
它不是标准的C和C ++,但OpenMP本身就是标准。
如何在linux中按所需顺序安排线程?
要实现所需的打印操作,您需要有一个全局变量,可以由您的两个线程访问。两个线程轮流访问全局变量variable
并执行操作(increment
和print
)。但是,要实现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;
}