谢谢大家的帮助,我正在分享以下代码,因为它可以提供线程安全的4字节事务/会话ID,或者至少我认为是:)。它将为16个线程/ 16个进程提供非常大量的唯一ID。 以下是该功能的基本测试,p_no是过程编号。
int get_id(int choice, unsigned int pid);
int start_(int id);
void *print_message_function( void *ptr );
void *print_message_function2( void *ptr );
unsigned int pid_arr[15][2];
int p_no = 1;
int main()
{
pthread_t thread1, thread2;
char *message1 = "Thread 1";
char *message2 = "Thread 2";
int iret1, iret2;
int s,f;
for (s=0;s<15;s++)
{
for (f=0;f<2;f++)
pid_arr[s][f]= 0;
}
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
iret2 = pthread_create( &thread2, NULL, print_message_function2, (void*) message2);
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
exit(0);
}
void *print_message_function( void *ptr )
{
int one=0;
get_id(1/*register*/,(unsigned int)pthread_self());
while (1)
{
int ret = get_id(0,(unsigned int)pthread_self());
printf("thread 1 = %u\n",ret);
sleep(1);
}
}
void *print_message_function2( void *ptr )
{
int one=0;
get_id(1/*register*/,(unsigned int)pthread_self());
while (1)
{
int ret = get_id(0,(unsigned int)pthread_self());
printf("thread 2 = %u\n",ret);
sleep(1);
}
}
int get_id(int choice, unsigned int pid)
{
int x;
if (choice==1) // thread registeration part
{
for(x=0;x<15;x++)
{
if (pid_arr[x][0] == 0)
{
pid_arr[x][0] = pid;
pid_arr[x][1] = ((p_no<<4) | x) << 24;
break;
}
}
}
int y;
for(y=0;y<15;y++) // tranaction ID part
{
if (pid_arr[y][0]==pid)
{
if(pid_arr[y][1] >= ((((p_no<<4) | y) << 24) | 0xfffffd) )
((p_no<<4) | x) << 24;
else
pid_arr[y][1]++;
return (unsigned int) pid_arr[y][1];
break;
}
}
}
答案 0 :(得分:1)
它不是线程安全的。例如,在注册部分中,以下行最终会成为问题:
1: if ( pid_arr[x][0] == 0 )
{
2: pid_arr[x][0] = pid;
如果thread1执行第1行然后在执行第2行之前发生了上下文切换,则thread2可以运行并执行第1行。此时,两个线程最终可以“拥有”pid_arr
中的相同位置阵列。或者说,执行第2行的最后一个将拥有该位置,而另一个将不拥有数组中的任何位置。
答案 1 :(得分:0)
读/写文件范围或外部变量的代码必须序列化,或者它不是线程安全的。
提供的示例不是线程安全的。