我写了以下程序。我希望这个功能按顺序打印1,2 程序等待一段时间(例如10秒),然后打印所有结果。
这是代码:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
void *thread_function(void *arg);
char message[] = "Hello World";
int run_now = 1;
int main()
{
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, (void *)message);
if (res != 0)
{
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
int print_count1 = 0;
while(print_count1++ < 20)
{
if (run_now == 1)
{
printf("1");
run_now = 2;
}
else
{
sleep(1);
}
}
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0)
{
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined. \n");
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg)
{
int print_count2 = 0;
while(print_count2++ < 20)
{
if (run_now == 2)
{
printf("2");
run_now = 1;
}
else
{
sleep(1);
}
}
}
我希望每1秒打印1,2,但程序会等待一段时间,然后完全打印所有字符串。谁能告诉我是什么原因?
答案 0 :(得分:3)
int run_now
,因此其访问权限需要受到保护。
为此,请使用互斥锁,例如:
...
int run_now = 1;
pthtread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int main()
{
...
while(print_count1++ < 20)
{
pthread_mutex_lock(&mutex);
int run_now_equals_1 = (run_now == 1);
if (run_now_equals_1)
{
printf("1");
run_now = 2;
}
pthread_mutex_unlock(&mutex);
if (!run_now_equals_1)
{
sleep(1);
}
}
...
}
void *thread_function(void *arg)
{
int print_count2 = 0;
while(print_count2++ < 20)
{
pthread_mutex_lock(&mutex);
int run_now_equals_2 = (run_now == 2);
if (run_now_equals_2)
{
printf("2");
run_now = 1;
}
pthread_mutex_unlock(&mutex);
if (!run_now_equals_2)
{
sleep(1);
}
}
}
答案 1 :(得分:1)
使用fprintf(stderr,"...")
代替printf
,或在fflush(stdout)
之后添加printf
。
这是因为stout
仅在操作系统决定刷新时才刷新,而stderr
在调用fprintf
后立即刷新。
答案 2 :(得分:1)
嗯,你的程序有一些问题。首先,printf
可以在内部缓冲内容,因此您不会看到它们。这可能就是你所指的。每个fflush
后,您需要stdout
printf
。更严重的问题是您的程序错误,因为它使用非原子非易失性变量进行通信。
在thread_function
中,编译器可以自由地将run_now
的加载移出循环并仅使用寄存器副本,因此循环不会注意到另一个线程更改了记忆中的价值。您应该始终使用原子内在函数来访问这样的共享变量。