我正在尝试做以下作业:
您将编写一个创建三个线程的程序。这些线程一次访问一个共享整数、缓冲区。缓冲区最初将设置为 0。每个线程都应在一条语句中打印其线程 ID、进程 ID 和缓冲区的当前值,然后将缓冲区递增 1。使用互斥锁来确保整个过程不被中断。让线程修改缓冲区 15 次。当每个线程完成后,它应该将其更改缓冲区的次数返回给主线程。
输出应如下所示:
TID: 3077897072, PID: 30656, Buffer: 0
TID: 3069504368, PID: 30656, Buffer: 1
TID: 3059014512, PID: 30656, Buffer: 2
TID: 3077897072, PID: 30656, Buffer: 3
TID: 3069504368, PID: 30656, Buffer: 4
TID: 3077897072, PID: 30656, Buffer: 5
TID: 3059014512, PID: 30656, Buffer: 6
TID: 3069504368, PID: 30656, Buffer: 7
TID: 3077897072, PID: 30656, Buffer: 8
TID: 3059014512, PID: 30656, Buffer: 9
TID: 3069504368, PID: 30656, Buffer: 10
TID: 3077897072, PID: 30656, Buffer: 11
TID: 3069504368, PID: 30656, Buffer: 12
TID: 3059014512, PID: 30656, Buffer: 13
TID: 3069504368, PID: 30656, Buffer: 14
TID 3077897072 worked on the buffer 5 times
TID 3069504368 worked on the buffer 6 times
TID 3059014512 worked on the buffer 4 times
Total buffer accesses: 15
这是我为解决作业而编写的代码(C 语言):
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
int buffer = 0;
const int NUM_MODIFICATIONS = 15;
pthread_mutex_t lock;
struct Solution {
unsigned long TID;
int mod;
};
void * thread_function() {
struct Solution *sol = malloc(sizeof *sol);
sol->TID = (unsigned long) pthread_self();
sol->mod = 0;
while(buffer < NUM_MODIFICATIONS) {
pthread_mutex_lock(&lock);
printf("TID: %lu, PID: %d, Buffer: %d\n", sol->TID, getpid(), buffer);
buffer++; sol->mod++;
pthread_mutex_unlock(&lock);
sleep(1);
}
return sol;
}
int main() {
pthread_t t1, t2, t3;
pthread_mutex_init(&lock, NULL);
pthread_create(&t1, NULL, thread_function, NULL);
pthread_create(&t2, NULL, thread_function, NULL);
pthread_create(&t3, NULL, thread_function, NULL);
void * out_void1, * out_void2, * out_void3;
struct Solution *out1, *out2, *out3;
pthread_join(t1, &out_void1);
pthread_join(t2, &out_void2);
pthread_join(t3, &out_void3);
out1 = out_void1;
out2 = out_void2;
out3 = out_void3;
printf("TID %lu worked on the buffer %d times\n", out1->TID, out1->mod);
printf("TID %lu worked on the buffer %d times\n", out2->TID, out2->mod);
printf("TID %lu worked on the buffer %d times\n", out3->TID, out3->mod);
printf("Total buffer accesses: %d\n", out1->mod + out2->mod + out3->mod);
pthread_mutex_destroy(&lock);
}
起初,我没有包含
sleep(1)
指令,这使得程序无法按预期工作(缓冲区将达到 17,不知道为什么,因为我想说互斥锁已正确设置)。
我的直觉告诉我,线程执行之间的一些分离可能会解决这个问题,所以我在锁解锁后添加了
sleep(1)
指令。现在,它确实起作用了,但现在这个程序总是让每个线程在缓冲区上工作 5 次,而我无法让它工作,因此某些线程比其他线程工作得多一点或少一点。
任何有关如何解决此问题的帮助将不胜感激。
问题是您在互斥体创建的独占区域之外访问
buffer
。
while(buffer < NUM_MODIFICATIONS) { // XXX WRONG
pthread_mutex_lock(&lock);
printf("TID: %lu, PID: %d, Buffer: %d\n", sol->TID, getpid(), buffer);
buffer++; sol->mod++;
pthread_mutex_unlock(&lock);
}