这是我的代码:
int BufferSize = 3;
int buffer[3] = {0,0,0};
int producer_cursor = 0;
int consumer_cursor = 0;
sem_t empty, mutex, full;
void* Producer(void *arg)
{
sem_wait(&empty);
sem_wait(&mutex);
printf("producer thread: #%d in critical setion\n", *((int*) arg));
int j;
for (j=0;j<BufferSize;j++) {
printf("%d", buffer[j]);
}
printf("\n");
buffer[producer_cursor] = 1;
producer_cursor = (++producer_cursor) % 3;
for (j=0;j<BufferSize;j++) {
printf("%d", buffer[j]);
}
printf("\n");
sem_post(&full);
sem_post(&mutex);
}
void * Consumer(void* arg)
{
sem_wait(&full);
sem_wait(&mutex);
printf("consumer thread: #%d in critical setion\n", *((int*) arg));
int j;
for (j=0;j<BufferSize;j++) {
printf("%d", buffer[j]);
}
printf("\n");
buffer[consumer_cursor] = 0;
consumer_cursor = (++consumer_cursor) % 3;
printf("after change\n");
for (j=0;j<BufferSize;j++) {
printf("%d", buffer[j]);
}
printf("\n");
sem_post(&empty);
sem_post(&mutex);
}
void main(int argc, char * argv[])
{
int n;
pthread_t *threads;
sem_init(&mutex, 0, 1);
sem_init(&empty, 0, 3);
sem_init(&full, 0, 0);
pthread_t consumers[NUM_COMSUMERS];
pthread_t producers[NUM_PRODUCERS];
int i;
for (i = 0; i < NUM_COMSUMERS; i++) {
pthread_create(consumers+i, NULL, Consumer, &i);
}
for (i = 0; i < NUM_PRODUCERS; i++) {
pthread_create(producers+i, NULL, Producer, &i);
}
for (i = 0; i < NUM_COMSUMERS; i++) {
pthread_join(consumers[i], NULL);
}
for (i = 0; i < NUM_PRODUCERS; i++) {
pthread_join(producers[i], NULL);
}
}
我得到的输出是:
producer thread: #1 in critical setion
000
100
consumer thread: #4 in critical setion
100
after change
000
producer thread: #0 in critical setion
000
010
consumer thread: #1 in critical setion
010
after change
000
producer thread: #1 in critical setion
000
001
producer thread: #2 in critical setion
001
101
consumer thread: #2 in critical setion
101
after change
100
consumer thread: #2 in critical setion
100
after change
000
producer thread: #2 in critical setion
000
010
consumer thread: #4 in critical setion
010
after change
000
除了计数应该在 0 到 4 之间之外,结果是预期的,而在这种情况下它没有“#3”。每次运行程序时,“#”都会改变。有时甚至只显示“#0”和“#1”。
最佳答案
pthread_create
的最后一个参数是问题所在。您传递了一个指向 i
的指针,但是 i
的值随着主循环的执行而改变。无法保证 i
仍然是 0
(或 1
或 2
或 3
) 当您的线程执行打印并且您尊重指针时。
尝试这个简单的改变;它会给你预期的结果:
int i;
int id[4] = { 1, 2, 3, 4 };
for (i = 0; i < NUM_COMSUMERS; i++) {
pthread_create(consumers+i, NULL, Consumer, id + i);
}
for (i = 0; i < NUM_PRODUCERS; i++) {
pthread_create(producers+i, NULL, Producer, id + i);
}
以上假设 NUM_CONSUMERS
和 NUM_PRODUCERS
为 4,需要重新设计以使其更通用。
或者,您不必传入指针,您可以执行以下操作:
for (i = 0; i < NUM_COMSUMERS; i++) {
pthread_create(consumers+i, NULL, Consumer, (void *)i);
}
for (i = 0; i < NUM_PRODUCERS; i++) {
pthread_create(producers+i, NULL, Producer, (void *)i);
}
并且在您的线程中,不要取消引用 arg,只需将其转换为 int
:
printf("producer thread: #%d in critical section\n", (int)arg);
和:
printf("consumer thread: #%d in critical section\n", (int)arg);
注意:在 64 位系统上,您将收到在指针和 int 之间进行转换的警告。
关于c - C 中的 Pthread_Create 导致奇怪的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22925093/