我正在编写一个程序,只是为了通过打印每个线程中的内容来查看线程的调度。我得到的是一些意想不到的输出。
虽然我在循环中的每个print语句之后更新了我的变量的值,但是输出显示print语句在更新其值之前多次执行相同的变量值。
为什么会这样?
我期待以下结果,
53674444272163,T35,1
53674444562178,T35,2
53674444563927,T35,3
53674444565225,T35,4
但实际上我得到了以下结果。
53674444272163,T35,1
53674444272163,T35,1
53674444272163,T35,1
53674444272163,T35,1
53674444272163,T35,1
53674444272163,T35,1
53674444272163,T35,1
53674444562178,T35,2
53674444562178,T35,2
53674444562178,T35,2
53674444562178,T35,2
53674444562178,T35,2
53674444562178,T35,2
53674444562178,T35,2
53674444563927,T35,3
53674444563927,T35,3
53674444563927,T35,3
53674444563927,T35,3
53674444563927,T35,3
53674444563927,T35,3
53674444563927,T35,3
53674444565225,T35,4
53674444565225,T35,4
53674444565225,T35,4
53674444565225,T35,4
53674444565225,T35,4
53674444565225,T35,4
53674444565225,T35,4
这是我的计划
#include <pthread.h>
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <sys/time.h>
#include <time.h> /* time_t, struct tm, time, localtime */
#include <mutex> // std::mutex
#include <sstream>
#include <sys/resource.h>
#include <sys/types.h>
#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
#define NTHREADS 100
#define MAX_COUNT 1000
using namespace std;
std::ostringstream out1;
ofstream fp1;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
unsigned long long int rdtsc_start(void)
{
unsigned a, d;
__asm__ volatile("rdtsc" : "=a" (a), "=d" (d));
return ((unsigned long long)a) | (((unsigned long long)d) << 32);;
}
/* This is our thread function. It is like main(), but for a thread*/
void *threadA(void *arg)
{
long my_id = (long)arg;
int check=0;
volatile long count = 0;
int j=0;
while(count++< MAX_COUNT)
{
unsigned long long time_x=rdtsc_start();
pthread_mutex_lock(&mutex1);
out1<<time_x<<",T"<<my_id<<","<<count<<"\n";
pthread_mutex_unlock(&mutex1);
// busy wait to consume CPU
volatile long ii=0;
while(ii++<50000);
}
fp1<<out1.str();
pthread_exit(NULL);
return NULL;
}
int main(void)
{
pid_t pid;
pid=getpid();
printf("Thread pid %d\n",pid);
fp1.open("result_Threaded_Process1.txt"); // in place of parent process
pthread_t threadid[NTHREADS];
int result;
//printf("Create %d threads\n", NTHREADS);
for(long i=0; i<NTHREADS; ++i)
{
result= pthread_create(&threadid[i], NULL, threadA, (void *)i);
if(result ==-1)
{
perror("Thread Creation Error: \n");
exit(EXIT_FAILURE);
}
}
// printf("Wait for threads and cleanup\n");
for (long i=0; i<NTHREADS; ++i)
{
pthread_join(threadid[i], NULL);
}
fp1.close();
return 0;
}
我在哪里犯错误? 提前感谢任何线索或提示,以了解输出。
我在Ubuntu 12.04下使用g ++。
编辑
接受的答案:
根据@Jason的评论,当我把
pthread_mutex_lock(&mutex1);
fp1<<out1.str();
pthread_mutex_unlock(&mutex1);
在主要功能中我得到了预期的结果
53674444272163,T35,1
53674444562178,T35,2
53674444563927,T35,3
53674444565225,T35,4
而当我把
pthread_mutex_lock(&mutex1);
fp1<<out1.str();
pthread_mutex_unlock(&mutex1);
我收到同样的声明(53674444272163,T35,1)打印了NTHREAD次。(53674444562178,T35,2)打印了NTHREAD次。
根据我的理解,我得到的输出是因为尽管每个线程只是正确地写入输出值,
53674444272163,T35,1
53674444562178,T35,2
所有线程都在退出时打印out1的值,所以我总是在NTHREAD时间打印相同的语句。
现在,我的问题是为什么我没有像我的ORIGINAL程序那样在没有互斥的情况下打印NSTREAD时间(53674444272163,T35,1)?
此外,有时根据我的ORIGINAL程序没有互斥锁我得到 26773分段错误(核心转储),而使用互斥锁时,分段错误从未发生过。为什么呢???
谢谢。
答案 0 :(得分:0)
我无法在我的盒子上复制你的结果(4个核心),但我找到了一些东西:
您正在打印out1 NTHREAD次的结果(在线程的末尾)。所有线程完成后(在pthread_joins之后的main()中)只打印出out1的值
当您读取打印到fp1时,您没有在out1上放置互斥锁。如果你提出建议#1,这并不重要,但我认为我是出于教育目的而指出的。
我认为#1是你的问题。希望这会有所帮助。
答案 1 :(得分:0)
你正在指向“我”的指针。一个正在旋转的线程。当你的循环启动时,这将会发生变化。我希望奇怪的行为与你看到的有点不同,但是尝试将你传入的id更改为每个create_thread调用的新内容......就像这样:
for(long i=0; i<NTHREADS; ++i)
{
int *id = new int;
*id = i;
result= pthread_create(&threadid[i], NULL, threadA, (void *)id);
if(result ==-1)
{
perror("Thread Creation Error: \n");
exit(EXIT_FAILURE);
}
}
这样做是为每个线程的id创建新内存,并确保main中的for循环不会更改该值,并且其他线程也无法访问。