使用互斥锁按顺序同步线程
Synchronizing threads in the order using mutexes
我有这个 C 程序,它必须按 0-6 的顺序显示线程。我正在使用互斥锁,但是当我尝试 运行 我的代码时,没有任何反应,也没有显示任何内容。此外,编译器没有显示错误
我使用了锁定和解锁互斥锁,但我不确定是否在正确的位置创建了它。
任何建议和帮助表示赞赏。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads
int num = 0;
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
int i;
pthread_t tid[7];
// Initialize random number generator
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
int rc;
// Create our threads
for (i = 0; i < 7; i++)
{
pthread_create(&tid[i], NULL, text, (void*)code[i]);
for (i = 0; i < 7; i++)
{ rc = pthread_mutex_lock(&a_mutex);
for (i = 0; i < 7; i++)
{
rc = pthread_mutex_unlock(&a_mutex);
}
}
}
//join threads
for (i=0; i<7; i++)
{
if (pthread_join(tid[i], NULL));
}
rc = pthread_mutex_destroy(&a_mutex);
// Exit main
return 0;
}
void *text(void *arg)
{
long n = (long)arg;
int rand_sec = rand() % (3 - 1 + 1) + 1; // Random num seconds to sleep
while (num != n) {} // Busy wait used to wait for our turn
num++; // Let next thread go
sleep(rand_sec); // Sleep for random amount of time
printf("This is thread %d.\n", n);
// Exit thread
pthread_exit(0);
}
找出问题的关键是问自己这个问题 "What is the piece of data which is shared amongst my 6 threads?" 是需要互斥保护的变量(读取和写入)在锁定的互斥锁块中。目前,您只是从单个主线程锁定和解锁互斥量,这实际上什么都不做。
你可能想要更接近这个的东西(虽然这可以大大简化 - 例如你可以完全删除睡眠):
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads
int num = 0;
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
int i;
pthread_t tid[7];
// Initialize random number generator
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
// Create our threads
for (i = 0; i < 7; i++)
pthread_create(&tid[i], NULL, text, (void*)code[i]);
//join threads
for (i=0; i<7; i++)
if (pthread_join(tid[i], NULL));
pthread_mutex_destroy(&a_mutex);
// Exit main
return 0;
}
void *text(void *arg)
{
long n = (long)arg;
long localNum = -1;
int rand_sec = rand() % (3 - 1 + 1) + 1; // Random num seconds to sleep
int rc;
while ( localNum != n )
{
rc = pthread_mutex_lock(&a_mutex);
localNum = num;
rc = pthread_mutex_unlock(&a_mutex);
sleep(rand_sec); // Sleep for random amount of time
}
printf("This is thread %d.\n", n);
rc = pthread_mutex_lock(&a_mutex);
num++; // Let next thread go
rc = pthread_mutex_unlock(&a_mutex);
pthread_exit(0);
}
这是代码的最小版本,删除了等待和随机化部分,因为它们会转移人们对锁如何工作的注意力。
线程自动排队等待互斥锁。
你需要在例程函数中请求锁。
永远记得关闭线程并释放所有可能的代码路径上的锁。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads
int num = 0;
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
int i;
pthread_t tid[7];
// Create our threads
for (i = 0; i < 7; i++)
{
pthread_create( &tid[i], NULL, text, (void*) & code[i] );
}
//join threads
for (i=0; i<7; i++)
{
pthread_join(tid[i], NULL);
}
pthread_mutex_destroy( & a_mutex );
// Exit main
return 0;
}
void *text(void *arg)
{
while(1){
pthread_mutex_lock(&a_mutex);
if (num == *(int *) arg){
printf("This is thread has the code %d\n",*(int *) arg);
num++;
pthread_mutex_unlock(&a_mutex);
pthread_exit(0);
}
pthread_mutex_unlock(&a_mutex);
}
}
@Anastasia Netz。您只需要在代码的关键部分使用 pthread_mutex_lock and pthread_mutex_unlock
互斥体,而不仅仅是在主线程中。请在您的代码中仔细识别您的关键部分(完成重要工作并且对所有执行线程通用但只有其中一个线程可以访问的部分)并在那里使用这些互斥体。
现在让我解释一下您的代码:
在您的代码中,您只是创建七个线程。在创建每个线程后,您只需简单地锁定互斥量一次并无缘无故地解锁七次。因此,在完成所有七次迭代(创建这七个线程的for
)之后,您已经七次锁定互斥锁并解锁了 (7*7=49) 四十九次。
这是完成这项工作的代码:
for (i = 0; i < 7; i++) {
pthread_create(&tid[i], NULL, text, (void*)code[i]);
for (i = 0; i < 7; i++)
{
rc = pthread_mutex_lock(&a_mutex);
for (i = 0; i < 7; i++)
{
rc = pthread_mutex_unlock(&a_mutex);
}
}}
请查看 Xvan 的代码。
我有这个 C 程序,它必须按 0-6 的顺序显示线程。我正在使用互斥锁,但是当我尝试 运行 我的代码时,没有任何反应,也没有显示任何内容。此外,编译器没有显示错误
我使用了锁定和解锁互斥锁,但我不确定是否在正确的位置创建了它。 任何建议和帮助表示赞赏。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads
int num = 0;
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
int i;
pthread_t tid[7];
// Initialize random number generator
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
int rc;
// Create our threads
for (i = 0; i < 7; i++)
{
pthread_create(&tid[i], NULL, text, (void*)code[i]);
for (i = 0; i < 7; i++)
{ rc = pthread_mutex_lock(&a_mutex);
for (i = 0; i < 7; i++)
{
rc = pthread_mutex_unlock(&a_mutex);
}
}
}
//join threads
for (i=0; i<7; i++)
{
if (pthread_join(tid[i], NULL));
}
rc = pthread_mutex_destroy(&a_mutex);
// Exit main
return 0;
}
void *text(void *arg)
{
long n = (long)arg;
int rand_sec = rand() % (3 - 1 + 1) + 1; // Random num seconds to sleep
while (num != n) {} // Busy wait used to wait for our turn
num++; // Let next thread go
sleep(rand_sec); // Sleep for random amount of time
printf("This is thread %d.\n", n);
// Exit thread
pthread_exit(0);
}
找出问题的关键是问自己这个问题 "What is the piece of data which is shared amongst my 6 threads?" 是需要互斥保护的变量(读取和写入)在锁定的互斥锁块中。目前,您只是从单个主线程锁定和解锁互斥量,这实际上什么都不做。
你可能想要更接近这个的东西(虽然这可以大大简化 - 例如你可以完全删除睡眠):
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads
int num = 0;
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
int i;
pthread_t tid[7];
// Initialize random number generator
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
// Create our threads
for (i = 0; i < 7; i++)
pthread_create(&tid[i], NULL, text, (void*)code[i]);
//join threads
for (i=0; i<7; i++)
if (pthread_join(tid[i], NULL));
pthread_mutex_destroy(&a_mutex);
// Exit main
return 0;
}
void *text(void *arg)
{
long n = (long)arg;
long localNum = -1;
int rand_sec = rand() % (3 - 1 + 1) + 1; // Random num seconds to sleep
int rc;
while ( localNum != n )
{
rc = pthread_mutex_lock(&a_mutex);
localNum = num;
rc = pthread_mutex_unlock(&a_mutex);
sleep(rand_sec); // Sleep for random amount of time
}
printf("This is thread %d.\n", n);
rc = pthread_mutex_lock(&a_mutex);
num++; // Let next thread go
rc = pthread_mutex_unlock(&a_mutex);
pthread_exit(0);
}
这是代码的最小版本,删除了等待和随机化部分,因为它们会转移人们对锁如何工作的注意力。
线程自动排队等待互斥锁。
你需要在例程函数中请求锁。
永远记得关闭线程并释放所有可能的代码路径上的锁。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads
int num = 0;
pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
int i;
pthread_t tid[7];
// Create our threads
for (i = 0; i < 7; i++)
{
pthread_create( &tid[i], NULL, text, (void*) & code[i] );
}
//join threads
for (i=0; i<7; i++)
{
pthread_join(tid[i], NULL);
}
pthread_mutex_destroy( & a_mutex );
// Exit main
return 0;
}
void *text(void *arg)
{
while(1){
pthread_mutex_lock(&a_mutex);
if (num == *(int *) arg){
printf("This is thread has the code %d\n",*(int *) arg);
num++;
pthread_mutex_unlock(&a_mutex);
pthread_exit(0);
}
pthread_mutex_unlock(&a_mutex);
}
}
@Anastasia Netz。您只需要在代码的关键部分使用 pthread_mutex_lock and pthread_mutex_unlock
互斥体,而不仅仅是在主线程中。请在您的代码中仔细识别您的关键部分(完成重要工作并且对所有执行线程通用但只有其中一个线程可以访问的部分)并在那里使用这些互斥体。
现在让我解释一下您的代码:
在您的代码中,您只是创建七个线程。在创建每个线程后,您只需简单地锁定互斥量一次并无缘无故地解锁七次。因此,在完成所有七次迭代(创建这七个线程的for
)之后,您已经七次锁定互斥锁并解锁了 (7*7=49) 四十九次。
这是完成这项工作的代码:
for (i = 0; i < 7; i++) {
pthread_create(&tid[i], NULL, text, (void*)code[i]);
for (i = 0; i < 7; i++)
{
rc = pthread_mutex_lock(&a_mutex);
for (i = 0; i < 7; i++)
{
rc = pthread_mutex_unlock(&a_mutex);
}
}}
请查看 Xvan 的代码。