Атомарные операции Vs Mutex

Сейчас наступило время многоядерных и многопроцессорных систем (даже в последних смартфонах уже 2+ ядер)

Основная проблема многопроцессорного программирование это проблемы одновременного доступа к данным...

Доступ к данным можно блокировать методом mutex-a (spin lock)
pthread_mutex_lock(&mutex);
// некая работа над глобальными данными
pthread_mutex_unlock(&mutex);

А можно при помощи атомарных операций
__sync_add_and_fetch( &global_int, 1 );

Сегодня пришло в голову проверить при каком количестве операций внутри блокируемого блока выгоднее использовать Mutex - а при каком такой-же набор __sync_ операций (т.е. косвенно протестировать сколько стоит pthread_mutex_lock VS __sync)


Фактически тест код mutex
for (i = 0; i < INC_TO; i++)
{
pthread_mutex_lock(&mutex);
for (int j = 0; j < MAX_OPS; j++)
global_int++;
pthread_mutex_unlock(&mutex);
}
И для атомик:

for (i = 0; i < INC_TO; i++)
{

for (int j = 0; j < MAX_OPS; j++)
__sync_add_and_fetch( &global_int, 1 );
}

Результаты тестов:  
при MAX_OPS < 10 -  лучше __sync_add_and_fetch, 
при MAX_OPS >= 10 -  лучше  pthread_mutex_lock  && pthread_mutex_unlock, 

Вывод:  если вам нужно обновить одновременно меньше 10-ти переменных  - при возможности  лучше использовать атомарные операции, иначе - блок pthread_mutex_lock  && pthread_mutex_unlock

Неожиданное поведение функции select

В Linux
man 2 select

НАЗВАНИЕ
       select,   pselect,  FD_CLR,  FD_ISSET,  FD_SET,  FD_ZERO  -  синхронное
       мультиплексирование ввода-вывода

Во FreeBSD - есть еще такая пометка:  "The default size of FD_SETSIZE is currently 1024. In order to accommodate programs which might potentially use a larger number of open files with select(), it is possible to increase this size by having the program define FD_SETSIZE before the inclusion of any header which includes <sys/types.h>." (Что в переводе означает что лимит FD_SET 1024 и чтобы его увеличить нужно переопределить дефайн...

Сейчас select редко где встретишь в проекте, а вот раньше она встречалась сплошь и рядом.
Одна из самых общераспространенных схем использования select:

struct timeval null_time;
null_time.tv_sec = 2;
null_time.tv_usec = 0;        
fd_set inSet;        
FD_ZERO(&inSet); 
FD_SET(descr, &inSet);  
int res = select(descr+1, &inSet, NULL, NULL, &null_time);

Данный фрагмент кода ожидает когда из сокета можно будет читать данные с таймаутом 2 секунды

И все у нас будет замечательно, пока в один прекрасный момент в нашей программе по какой-то причине не появится 1024+ открытых файлов и значение descr станет больше 1024. И в этот чудесный день функция, как ожидается не вернет -1 (ошибочное значение), а замечательно потрет память за переменной fd_set inSet, что приведет к очень сложно отлаживаемым багам.

Вот пример кода который демонстрирует затирание:
#include <sys/time.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>


int main()
{
        int descr;
        for (int i = 0; i < 1024; i++)
        {
                descr = open("/dev/null", O_RDONLY);
                if (descr < 0)
                {
                        printf("Can't create descr\n");
                        return -1;
                }
        }
        struct timeval null_time;
        null_time.tv_sec  = 2;
null_time.tv_usec = 0;

        fd_set  inSet;
        char pad[] = "1234567890abcdefg";
        printf("pad before select [%s]\n", pad);
        FD_ZERO(&inSet);
        FD_SET(descr, &inSet);
        int res = select(descr+1, &inSet, NULL, NULL, &null_time);
        printf("Pad after select [%s], res=%d\n", pad, res);
}

$ g++ testselect.cpp
$ ./a.out
Pad bafore select [1234567890abcdefg]
Pad after [], res=1

Для избежания затирания я рекомендую использовать poll, для большого числа соединений - epoll. Или в крайнем случае сделать проверку значения descr перед выполнением select


Неприятные последствия при переходе с 32-х битной на 64-х битную

  • 21.02.12, 08:47
  • php
При переходе с 32-х битной на 64-х битную версию PHP выплывает очень неприятный сюрприз - все функции, которые возвращали отрицательное целое число (crc32, ip2long, etc), при тех же данных, будут возвращать положительное число.

Результат работы следующего кода:
<?php
echo crc32('habrahabr test crc32');
?>

На 32х битах = -982057838, на 64х битах = 3312909458, фактически это одно и тоже число - 0хc576fc92, разница только в интерпретации знакового бита. Если это число дальше используется, например для вставки в Mysql (в поле типа signed int), то вместо ожидаемых 2х одинаковых записей мы получим: -982057838 и 2147483647.

Данная особенность связана с тем, что в PHP внутренним представлением целого числа является long, который соответственно на 32х битных системах является 4х байтовым, а на 64х битных 8-ми байтовым. Проблема выплывает из-за того что при выводе данных php использует шаблон вывода "%ld", а знаковым считается 32-й или 64-й бит в зависимости от битности сборки PHP.

Пути решения проблемы:
1) Выставить знаковый бит:
$crc = crc32($num);
if($crc & 0x80000000) 
$crc -= 2<<31;

2) При выводе использовать свой шаблон: (s)printf("%d", $crc) или (s)printf("%u", $crc).
3) Использовать 32-х битную версию PHP.

Новый сервис Радио (radio.i.ua)

  • 02.09.11, 18:03



Рады предложить вашему вниманию новый сервис Радио


Евротрип

Ух
3510км, 10 дней, море удовольствия :) 
Киев - Краковец - Краков - Величка - Катавицы - Вроцлав - Прага - Карловы Вары - Прага - Будапешт - Львов - Киев ...

Правила дорожного движения:







продолжение следует...

Widget popup

Если надо из виджета открыть окно (например для того чтобы показать больше информации),
Нужно повесить на клик создание новой активности у которой в манифесте прописан стиль

 "@android:style/Theme.Dialog"

<activity android:name=".Info" android:label="@string/app_name" android:theme="@android:style/Theme.Dialog">
<intent-filter>
        <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.INFO" />
</intent-filter>
</activity>


import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.PopupWindow;
import android.widget.RemoteViews;

public class Widget extends AppWidgetProvider
{    
    public void onReceive(Context context, Intent intent)
    {
        String action = intent.getAction();
        if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action))
        {
       
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
            
            Intent active = new Intent(context, Info.class);
            PendingIntent actionPendingIntent = PendingIntent.getActivity(context, 0, active, PendingIntent.FLAG_UPDATE_CURRENT); 
            views.setOnClickPendingIntent(R.id.Widget, actionPendingIntent);
                                    
            AppWidgetManager.getInstance(context).updateAppWidget(intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS), views);
        }
    }
}



Начало :)


Вот начал работы над I.UA widget-ом под андроид





Тут так принято!

Есть три обезьяны в клетке. Они хотят есть, в центре клетки стоит стремянка, над ней висят бананы. Одна обезьяна полезла за ними — всех троих тут же окатили холодной водой из пожарного шланга. Так повторилось несколько раз, пока они и думать забыли про эти бананы. 
Потом одну из обезьян увели, привели новую. Она, не долго думая, полезла за бананами. Но! Две остальных её тут же оттянули от стремянки и дали ей по голове. Потом так поменяли вторую обезьяну, и все повторилось. Наконец — заменили третью. Когда она полезла за бананами, две других опять стянули её со стремянки и дали по голове. 

В итоге — в клетке оказалось три обезьяны, ни одна из которых не получала холодного душа за попытку достать бананы, но все они сторонились стремянки как огня. Почему? Потому, что тут так принято! 

Мы в Android Market

  • 23.12.10, 14:01
Приложения photo.i.ua добавлено в Android Market




Ссылка (или можно просто в поиске дать I.UA): 


Башня

  • 19.12.10, 18:53
Вот игрались сегодня dada




Вот результаты игры:



Сторінки:
1
2
3
5
попередня
наступна